From 0473812207e2531bc9c87259363a6ca486a70c5a Mon Sep 17 00:00:00 2001 From: John Bowdre Date: Thu, 16 Jun 2022 10:26:59 -0500 Subject: [PATCH] new workflow: VM Post-Provision --- .../Workflows/VM Post-Provision/README.md | 15 ++++++++ .../Tasks/01_get_vm_object.js | 9 +++++ .../VM Post-Provision/Tasks/02_set_notes.js | 15 ++++++++ .../Tasks/03_create_dns_record.js | 34 ++++++++++++++++++ .../Workflows/VM Post-Provision/schema.png | Bin 0 -> 20145 bytes 5 files changed, 73 insertions(+) create mode 100644 Orchestrator/Workflows/VM Post-Provision/README.md create mode 100644 Orchestrator/Workflows/VM Post-Provision/Tasks/01_get_vm_object.js create mode 100644 Orchestrator/Workflows/VM Post-Provision/Tasks/02_set_notes.js create mode 100644 Orchestrator/Workflows/VM Post-Provision/Tasks/03_create_dns_record.js create mode 100644 Orchestrator/Workflows/VM Post-Provision/schema.png diff --git a/Orchestrator/Workflows/VM Post-Provision/README.md b/Orchestrator/Workflows/VM Post-Provision/README.md new file mode 100644 index 0000000..d584a73 --- /dev/null +++ b/Orchestrator/Workflows/VM Post-Provision/README.md @@ -0,0 +1,15 @@ +# VM Post-Provision workflow +Performs post-deploy tasks like adding notes to the VM object and creating static DNS records (if needed). + +![Schema](schema.png) + +## Inputs/Outputs +| Name | Type | Direction | Description | +|:--- |:--- |:---|:---| +| `inputProperties` | Properties | Input | full request payload from vRA | + +## Variables +| Name | Type | Value | Description | +|:--- |:--- |:--- |:--- | +| `vm` | VC:VirtualMachine| | virtual machine object | +| `dnsHost` | CompositeType(sshHost:string,sshUser:string,sshPass:SecureString,dnsServers:Array/string,supportedDomains:Array/string):dnsConfig | `Endpoints: dnsHost` | object which stores endpoint and credential details for DNS operations | diff --git a/Orchestrator/Workflows/VM Post-Provision/Tasks/01_get_vm_object.js b/Orchestrator/Workflows/VM Post-Provision/Tasks/01_get_vm_object.js new file mode 100644 index 0000000..e524d7a --- /dev/null +++ b/Orchestrator/Workflows/VM Post-Provision/Tasks/01_get_vm_object.js @@ -0,0 +1,9 @@ +/* JavaScript: get VM object + Retrieves a VC:VirtualMachine object matching the resourceName from the VcPlugin + Inputs: inputProperties (Properties) + Outputs: vm (VC:VirtualMachine) +*/ +var name = inputProperties.resourceNames[0]; +var vms = VcPlugin.getAllVirtualMachines(null, name); +System.debug("Found VM object: " + vms[0]); +vm = vms[0]; \ No newline at end of file diff --git a/Orchestrator/Workflows/VM Post-Provision/Tasks/02_set_notes.js b/Orchestrator/Workflows/VM Post-Provision/Tasks/02_set_notes.js new file mode 100644 index 0000000..e3535c9 --- /dev/null +++ b/Orchestrator/Workflows/VM Post-Provision/Tasks/02_set_notes.js @@ -0,0 +1,15 @@ +/* JavaScript: set notes + Adds notes and custom attributes to the VC:VirtualMachine + Inputs: inputProperties (Properties), vm (VC:VirtualMachine) + Outputs: none +*/ +var notes = inputProperties.customProperties.description; +var poc = inputProperties.customProperties.poc; +var ticket = inputProperties.customProperties.ticket; +var spec = new VcVirtualMachineConfigSpec(); +spec.annotation = notes; +vm.reconfigVM_Task(spec); +System.log("Set VM description: " + notes); +System.getModule("com.vmware.library.vc.customattribute").setOrCreateCustomField(vm, "Point of Contact", poc); +System.getModule("com.vmware.library.vc.customattribute").setOrCreateCustomField(vm, "Ticket", ticket); +System.log("Set VM attributes: Point of Contact " + poc + ", Ticket " + ticket); \ No newline at end of file diff --git a/Orchestrator/Workflows/VM Post-Provision/Tasks/03_create_dns_record.js b/Orchestrator/Workflows/VM Post-Provision/Tasks/03_create_dns_record.js new file mode 100644 index 0000000..da9a218 --- /dev/null +++ b/Orchestrator/Workflows/VM Post-Provision/Tasks/03_create_dns_record.js @@ -0,0 +1,34 @@ +/* JavaScript: create dns record + Optionally creates a static record in Microsoft DNS by way of an SSH bastion host. + Inputs: inputProperties (Properties), dnsHost (CompositeType(sshHost:string,sshUser:string,sshPass:SecureString,dnsServers:Array/string,supportedDomains:Array/string):dnsConfig) + Outputs: none +*/ +var staticDns = inputProperties.customProperties.staticDns; +var hostname = inputProperties.resourceNames[0]; +var dnsDomain = inputProperties.customProperties.domain; +var ipAddress = inputProperties.addresses[0]; +var created = false; +if (staticDns == "true" && dnsHost.supportedDomains.indexOf(dnsDomain) >= 0) { + System.log("Attempting to create DNS record for " + hostname + "." + ipAddress + "..."); + var sshSession = new SSHSession(dnsHost.sshHost, dnsHost_sshUser); + System.debug("Connecting to " + dnsHost.sshHost + "..."); + sshSession.connectWithPassword(dnsHost.sshPass); + for each (dnsServer in dnsHost.dnsServers) { + if (created == false) { + System.debug("Using DNS Server " + dnsServer + "..."); + var sshCommand = 'Add-DnsServerResourceRecordA -ComputerName ' + dnsServer + ' -Name ' + hostname + ' -ZoneName ' + dnsDomain + ' -AllowUpdateAny -IPv4Address ' + ipAddress; + System.debug("sshCommand: " + sshCommand); + sshSession.executeCommand(sshCommand, true); + if (sshSession.exitCode == 0) { + System.log("Successfully created DNS record."); + created = true; + } + } + } + sshSession.disconnect(); + if (created == false) { + System.warn("Error! Unable to create DNS record."); + } +} else { + System.log("Not trying to do DNS."); +} \ No newline at end of file diff --git a/Orchestrator/Workflows/VM Post-Provision/schema.png b/Orchestrator/Workflows/VM Post-Provision/schema.png new file mode 100644 index 0000000000000000000000000000000000000000..a3e8368f01b08dd89e8cf36dfe7eb93e48f42453 GIT binary patch literal 20145 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 Kb6Mw<&;$TOdc7$C literal 0 HcmV?d00001