388 lines
12 KiB
YAML
388 lines
12 KiB
YAML
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
Namespaces:
|
|
=: io.murano.resources
|
|
std: io.murano
|
|
sys: io.murano.system
|
|
|
|
|
|
Name: Instance
|
|
Extends: std:CloudResource
|
|
|
|
Properties:
|
|
name:
|
|
Contract: $.string().notNull()
|
|
flavor:
|
|
Contract: $.string().notNull()
|
|
image:
|
|
Contract: $.string()
|
|
Default: null
|
|
keyname:
|
|
Contract: $.string()
|
|
Default: null
|
|
openstackId:
|
|
Contract: $.string()
|
|
Usage: Out
|
|
availabilityZone:
|
|
Contract: $.string().notNull()
|
|
Default: nova
|
|
agent:
|
|
Contract: $.class(sys:Agent)
|
|
Usage: Runtime
|
|
ipAddresses:
|
|
Contract: [$.string()]
|
|
Usage: Out
|
|
networks:
|
|
Contract:
|
|
useEnvironmentNetwork: $.bool().notNull()
|
|
useFlatNetwork: $.bool().notNull()
|
|
customNetworks: [$.class(Network).notNull()]
|
|
primaryNetwork: $.class(Network).notOwned()
|
|
Default:
|
|
useEnvironmentNetwork: true
|
|
useFlatNetwork: false
|
|
customNetworks: []
|
|
primaryNetwork: null
|
|
assignFloatingIp:
|
|
Contract: $.bool().notNull()
|
|
Default: false
|
|
floatingIpAddress:
|
|
Contract: $.string()
|
|
Usage: Out
|
|
securityGroupName:
|
|
Contract: $.string()
|
|
Default: null
|
|
sharedIps:
|
|
Contract:
|
|
- $.class(std:SharedIp)
|
|
Usage: InOut # as it is set in setSharedIps
|
|
volumes:
|
|
Contract:
|
|
$.string().notNull(): $.class(Volume).notNull()
|
|
blockDevices:
|
|
Contract:
|
|
- volume: $.class(Volume).notNull()
|
|
deviceName: $.string()
|
|
deviceType: $.string().check($ in list(disk, cdrom, null))
|
|
bootIndex: $.int()
|
|
Default: []
|
|
joinedNetworks:
|
|
Contract:
|
|
- network: $.class(Network).notNull()
|
|
ipList: [$.string().notNull()]
|
|
Usage: Out
|
|
|
|
Methods:
|
|
initialize:
|
|
Body:
|
|
- $._environment: $.find(std:Environment).require()
|
|
- $.agent: new(sys:Agent, host => $)
|
|
- $.resources: new(sys:Resources)
|
|
- $.instanceTemplate: {}
|
|
- $._floatingIpOutputName: null
|
|
|
|
# Called after the Instance template pieces are in place. It
|
|
# is at this stage alterations to the template should be made
|
|
prepareStackTemplate:
|
|
Arguments:
|
|
instanceTemplate:
|
|
Contract: {}
|
|
Body:
|
|
- Return: $instanceTemplate
|
|
|
|
setSharedIps:
|
|
Arguments:
|
|
ips:
|
|
Contract:
|
|
- $.class(std:SharedIp)
|
|
Body:
|
|
$.sharedIps: $ips
|
|
|
|
beginDeploy:
|
|
Body:
|
|
- $.validateBootSource()
|
|
- $region: $.getRegion()
|
|
- $securityGroupName: coalesce(
|
|
$.securityGroupName,
|
|
$region.securityGroupManager.defaultGroupName
|
|
)
|
|
- $.createDefaultInstanceSecurityGroupRules($securityGroupName)
|
|
- $.detectPrimaryNetwork()
|
|
- $.ensureSharedIpsDeployed()
|
|
- $.ensureNetworksDeployed()
|
|
- If: $.networks.useEnvironmentNetwork and $region.defaultNetworks.environment!=null
|
|
Then:
|
|
$.joinNet($region.defaultNetworks.environment, $securityGroupName)
|
|
- If: $.networks.useFlatNetwork and $region.defaultNetworks.flat!=null
|
|
Then:
|
|
$.joinNet($region.defaultNetworks.flat, $securityGroupName)
|
|
- $.networks.customNetworks.select($this.joinNet($, $securityGroupName))
|
|
|
|
- $preparedUserData: $.prepareUserData()
|
|
# Create MQ queue to communicate with the VM
|
|
- $.agent.prepare()
|
|
- $properties:
|
|
name: $.name
|
|
flavor: $.flavor
|
|
availability_zone: $.availabilityZone
|
|
user_data: $preparedUserData.data
|
|
user_data_format: $preparedUserData.format
|
|
key_name: $.keyname
|
|
|
|
- If: len($.blockDevices) > 0
|
|
Then:
|
|
- $bdmDefinition: $.blockDevices.select($this.buidBlockDeviceDefinition($))
|
|
- $properties.block_device_mapping_v2: $bdmDefinition
|
|
Else:
|
|
$properties.image: $.image
|
|
|
|
- $template:
|
|
resources:
|
|
$.name:
|
|
type: 'OS::Nova::Server'
|
|
properties: $properties
|
|
|
|
outputs:
|
|
format('{0}-assigned-ips', $.name):
|
|
description: format('Network IPs assigned to {0} instance', $.name)
|
|
value:
|
|
get_attr: [ $.name, networks ]
|
|
format('{0}-id', $.name):
|
|
description: format('ID of {0} instance', $.name)
|
|
value:
|
|
get_resource: $.name
|
|
|
|
- $.instanceTemplate: $.instanceTemplate.mergeWith($template)
|
|
- $.volumes.items().select(
|
|
$.unpack(path, volume) -> $this.attachVolume($path, $volume))
|
|
|
|
# Any additional template preparation
|
|
- $.instanceTemplate: $.prepareStackTemplate($.instanceTemplate)
|
|
- $region.stack.updateTemplate($.instanceTemplate)
|
|
|
|
endDeploy:
|
|
Body:
|
|
- $region: $.getRegion()
|
|
- $region.stack.push()
|
|
- $outputs: $region.stack.output()
|
|
- $netIdToIpsMap: $outputs.get(format('{0}-assigned-ips', $this.name))
|
|
- $.ipAddresses: $netIdToIpsMap.values().flatten().distinct()
|
|
- $.openstackId: $outputs.get(format('{0}-id', $this.name))
|
|
- If: $._floatingIpOutputName != null
|
|
Then:
|
|
- $.floatingIpAddress: $outputs.get($._floatingIpOutputName)
|
|
- If: $.floatingIpAddress != null
|
|
Then: $.setAttr(fipAssigned, true)
|
|
- $._environment.instanceNotifier.trackCloudInstance($this)
|
|
- $.joinedNetworks: $this.joinedNetworks.distinct().select({
|
|
'network' => $['network'],
|
|
'ipList' => $['network'].getInstanceIpList($this)})
|
|
|
|
deploy:
|
|
Body:
|
|
- $this.beginDeploy()
|
|
- $this.endDeploy()
|
|
|
|
detectPrimaryNetwork:
|
|
Body:
|
|
- $region: $.getRegion()
|
|
- $._primaryNetwork: null
|
|
- If: $.networks.primaryNetwork != null
|
|
Then:
|
|
- $._primaryNetwork: $.networks.primaryNetwork
|
|
Else:
|
|
- If: $.networks.useEnvironmentNetwork and $region.defaultNetworks.environment!=null
|
|
Then:
|
|
- $._primaryNetwork: $region.defaultNetworks.environment
|
|
Else:
|
|
- If: $.networks.useFlatNetwork and $region.defaultNetworks.flat!=null
|
|
Then:
|
|
- $._primaryNetwork: $region.defaultNetworks.flat
|
|
Else:
|
|
- If: $.networks.customNetworks!= null
|
|
Then:
|
|
- $._primaryNetwork: $.networks.customNetworks.first(null)
|
|
|
|
ensureNetworksDeployed:
|
|
Body:
|
|
- $region: $.getRegion()
|
|
- If: $.networks.useEnvironmentNetwork and $region.defaultNetworks.environment!=null
|
|
Then:
|
|
- $region.defaultNetworks.environment.deploy()
|
|
- If: $.networks.useFlatNetwork and $region.defaultNetworks.flat!=null
|
|
Then:
|
|
- $region.defaultNetworks.flat.deploy()
|
|
- $.networks.customNetworks.pselect($.deploy())
|
|
|
|
ensureSharedIpsDeployed:
|
|
Body:
|
|
- $.sharedIps.pselect($.deploy())
|
|
|
|
joinNet:
|
|
Arguments:
|
|
- net:
|
|
Contract: $.class(Network).notNull()
|
|
- securityGroupName:
|
|
Contract: $.string()
|
|
Body:
|
|
- $primary: $net = $._primaryNetwork
|
|
- $assignFip: $primary and $.assignFloatingIp and not $.getAttr(fipAssigned, false)
|
|
- $sharedIps: []
|
|
- If: $primary
|
|
Then:
|
|
$sharedIps: $.sharedIps
|
|
- $joinResult: $net.joinInstance(
|
|
instance => $this,
|
|
securityGroupName => $securityGroupName,
|
|
assignFloatingIp => $assignFip,
|
|
sharedIps => $sharedIps
|
|
)
|
|
- $.setAttr(instanceResources, $.getAttr(instanceResources, []).concat($joinResult.get(instanceResources, [])))
|
|
- $.setAttr(instanceOutputs, $.getAttr(instanceOutputs, []).concat($joinResult.get(instanceOutputs, [])))
|
|
|
|
- If: $joinResult.template != null
|
|
Then:
|
|
- $.instanceTemplate: $.instanceTemplate.mergeWith($joinResult.template)
|
|
|
|
- If: $joinResult.get(portRef) != null
|
|
Then:
|
|
- $template:
|
|
resources:
|
|
$.name:
|
|
properties:
|
|
networks:
|
|
- port:
|
|
$joinResult.portRef
|
|
- $.instanceTemplate: $.instanceTemplate.mergeWith($template)
|
|
- If: $joinResult.get(secGroupName) != null
|
|
Then:
|
|
- $template:
|
|
resources:
|
|
$.name:
|
|
properties:
|
|
security_groups:
|
|
- $joinResult.secGroupName
|
|
- $.instanceTemplate: $.instanceTemplate.mergeWith($template)
|
|
|
|
- $._floatingIpOutputName: coalesce($._floatingIpOutputName, $joinResult.instanceFipOutput)
|
|
- $this.joinedNetworks: $this.joinedNetworks.append({network => $net})
|
|
|
|
attachVolume:
|
|
Arguments:
|
|
- path:
|
|
Contract: $.string().notNull()
|
|
- volume:
|
|
Contract: $.class(Volume).notNull()
|
|
Body:
|
|
- $attachment: $volume.attachTo($this, $path)
|
|
- $.instanceTemplate: $.instanceTemplate.mergeWith($attachment.template)
|
|
- $.setAttr(instanceResources, $.getAttr(instanceResources, []).concat($attachment.get(instanceResources, [])))
|
|
- $.setAttr(instanceOutputs, $.getAttr(instanceOutputs, []).concat($attachment.get(instanceOutputs, [])))
|
|
|
|
buidBlockDeviceDefinition:
|
|
Arguments:
|
|
blockDevice:
|
|
Contract:
|
|
volume: $.class(Volume).notNull()
|
|
deviceName: $.string()
|
|
deviceType: $.string().check($ in list(disk, cdrom, null))
|
|
bootIndex: $.int()
|
|
|
|
Body:
|
|
- $blockDevice.volume.deploy()
|
|
- Return:
|
|
device_name: $blockDevice.deviceName
|
|
volume_id: $blockDevice.volume.getRef()
|
|
device_type: $blockDevice.deviceType
|
|
boot_index: $blockDevice.bootIndex
|
|
|
|
beginReleaseResources:
|
|
Body:
|
|
- $region: $.getRegion()
|
|
- $template: $region.stack.current()
|
|
- If: $template.get(resources) and $template.get(outputs)
|
|
Then:
|
|
- $resourcesToDelete: list($.name).concat($.getAttr(instanceResources, []))
|
|
- $lenBefore: len($template.resources)
|
|
- $template.resources: $template.resources.deleteAll($resourcesToDelete)
|
|
- If: $lenBefore > len($template.resources)
|
|
Then:
|
|
- $._environment.instanceNotifier.untrackCloudInstance($this)
|
|
|
|
- $outputsToDelete: list(
|
|
'{0}-assigned-ips'.format($.name),
|
|
'{0}-id'.format($.name)).concat($.getAttr(instanceOutputs, []))
|
|
- $template.outputs: $template.outputs.deleteAll($outputsToDelete)
|
|
|
|
- $region.stack.setTemplate($template)
|
|
|
|
endReleaseResources:
|
|
Body:
|
|
- $region: $.getRegion()
|
|
- $template: $region.stack.current()
|
|
- If: $template.get(resources) and $template.get(outputs)
|
|
Then:
|
|
- $region.stack.push()
|
|
- $.setAttr(instanceResources, [])
|
|
- $.setAttr(instanceOutputs, [])
|
|
- $.setAttr(fipAssigned, false)
|
|
- $.openstackId: null
|
|
- $.ipAddresses: []
|
|
- $.floatingIpAddress: null
|
|
|
|
releaseResources:
|
|
Body:
|
|
- $this.beginReleaseResources()
|
|
- $this.endReleaseResources()
|
|
|
|
validateBootSource:
|
|
Body:
|
|
- If: $.image = null and len($.blockDevices) = 0
|
|
Then:
|
|
- $msg: format('Neither image nor bootable volumes is specified for instance {0}', $.name)
|
|
- Throw: ResourceNotFound
|
|
Message: $msg
|
|
- If: $.image != null and len($.blockDevices) > 0
|
|
Then:
|
|
- $msg: 'Both image and list of bootable volumes are specified'
|
|
- Throw: ResourceConflict
|
|
Message: $msg
|
|
|
|
destroy:
|
|
Body:
|
|
- $.releaseResources()
|
|
|
|
|
|
createDefaultInstanceSecurityGroupRules:
|
|
Arguments:
|
|
- groupName:
|
|
Contract: $.string().notNull()
|
|
|
|
prepareUserData:
|
|
Body:
|
|
Return:
|
|
data: null
|
|
# Valid values are HEAT_CFNTOOLS, RAW and SOFTWARE_CONFIG
|
|
format: HEAT_CFNTOOLS
|
|
|
|
isDeployed:
|
|
Body:
|
|
- $region: $.getRegion()
|
|
- $template: $region.stack.current()
|
|
- Return: $template.get(resources, {}).containsKey($.name)
|
|
|
|
getRef:
|
|
Body:
|
|
Return:
|
|
get_resource: $.name
|