Changing the instance hostname with a workflow/task

I have a external api wich I have connected to morpheus wich returns a free hostname to use for the instance. I would like to set the hostname of the instance to the result of the HTTP API call.

I have tried alot of things, but cant figure it out, can someone point me into the right direction?

Hey @Alex,

So you can utilize the “Configuration Phase”, which triggers calls before the payload is submitted.

  1. Create this Groovy task:
    println("${spec.encodeAsJson().toString()}")

  2. Put that task in a provisioning workflow under the “Configuration Phase”.

  3. Deploy a new VM with that workflow selected. The configuration phase will run and task output will show the type of data you have available.

Essentially, there is a variable spec that is available in this phase. You can modify that JSON payload, and then output it.

Note, you must have your last configuration phase task only output the spec JSON, no other stdout. You must also set the Result Type of the task to “JSON”.

A few examples in the forums:

And an example PowerShell Core code I use. This:

  1. Requests an IP from an IP Pool via the Morpheus API.
  2. Sets a temp name on the request for the IP.
  3. Updates the VM hostname based on the IP address hash.
  4. Echoes out the spec JSON body to pick the changes up.
$configJson = '<%=spec.encodeAsJson().toString()%>'
$bearer = "<%=morpheus.apiAccessToken%>"
$morphUrl = '<%=morpheus.applianceUrl%>'
$ContentType = 'application/json'
$morphHeader = @{
    "Authorization" = "BEARER $bearer"
}
$poolApi = 'api/networks/pools/'
$configJson = $configJson | convertfrom-json -Depth 10
$pool = $configJson.networkInterfaces.network.pool.id

### Functions
function ipv4ToHexString($ipv4){
 
    # Validation
    $valid = $true
    $ipv4.split(".") | foreach { if([int]$_ -ge 0 -and [int]$_ -le 255) { } else { $valid = $false } }
 
    if($valid -eq $true){
 
        # Conversion
        $hexString = ""
        $hexList = @("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f")
        $ipv4.split(".") | foreach {
            $mod = [int]$_ % 16
            $first = $hexList[(([int]$_ - $mod) / 16)]
            $second = $hexList[$mod]
            $hexString += $first+$second
        } 
        return $hexString
    }
    else{
        return $false
    }
}

#################################################################################
### Script
$tempName = get-random
$poolBody = @"
{
    "createDns": false,
    "networkPoolIp": {
      "hostname": $tempName
    }
}
"@

# Request IP
$ip = (Invoke-WebRequest -Method POST -Uri ($morphUrl + $poolApi + $pool + '/ips') -SkipCertificateCheck -Headers $morphHeader -Body $poolBody -ContentType $ContentType).content | convertfrom-json
$ip = $ip.networkPoolIp

# Generate Name Hash
$hashName = (ipv4ToHexString -ipv4 $ip.ipAddress).toUpper()
$hashName = "$hashName"

$configJson.instance.name = $hashName
$configJson.instance.hostName = $hashName

$configJson = $configJson | ConvertTo-Json -Depth 10

$spec = @"
{
    "spec": $configJson
}
"@

$spec

#spec #configurationphase

1 Like

I will note, there is a roadmap item to allow policy plugins. This would enable a cleaner way to use 3rd party platforms for things like naming policies.

Thank you cbunge for your fast reply. I got it working!!

1 Like

Nice!

I have a follow up question.

as I read in the docs I set an HTTP Api wich returns a single value that should be stored in:
<%=results.taskCode%> or <%=results["Task Name"]%> variable.

Where and how can I use this variable, cause when I try to use it in another task in the same workflow I cant seem to access it. Is it even possible to use results from earlier tasks in the next one?

A few things about that.

  1. Your tasks need to set the code (which will be the fieldName in results.fieldName), and the result type. Almost always this is Single Value. I often just output my JSON as a string and use Single Value instead of JSON

  2. Results capture the entirety of stdout. So make sure you only echo out the data you need in the task.

  3. Results only persist within a phase. I.E - You can’t generate a result in pre-provisioning and use it in post-provisioning. You would have to regenerate it, or maybe store that data somewhere on the system you are automating temporarily.

Sorry if that repeated anything, first post of the day :slight_smile: :coffee:

first of, thnx alot for the super fast response, enjoy your coffee

I have a api call set to single value wich if I execute it indeed outputs a string with my new hostname. the code is set to newHostName

Then I run a python script wich changes the hostname, wich works if I just give it a string of my own. but how do I access the variable newHostName in my python script?

for python it would be a var like:

hostname = str(morpheus['results']['newHostName']).strip()

Note: I added the strip() because I found sometimes my stdout capture adds a trailing space.

1 Like