murano/meta/io.murano/Classes/resources/Instance.yaml

428 lines
14 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
- MetadataAware
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
securityGroups:
Contract: [$.string()]
Default: []
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
#policies: anti-affinity, affinity
instanceAffinityGroup:
Contract: $.class(InstanceAffinityGroup)
Methods:
.init:
Body:
- $._environment: $.find(std:Environment).require()
- $.agent: new(sys:Agent, host => $)
- $.resources: new(sys:Resources)
- $.instanceTemplate: {}
- $._floatingIpOutputName: null
- $.volumes.values().concat($this.blockDevices.volume).select(
sys:GC.subscribeDestruction($, $this, _onReferencedResourceDelete))
- If: $.instanceAffinityGroup != null
Then: sys:GC.subscribeDestruction(
$this.instanceAffinityGroup, $this, _onReferencedResourceDelete)
# 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, $this.securityGroups)
- If: $.networks.useFlatNetwork and $region.defaultNetworks.flat!=null
Then:
$.joinNet($region.defaultNetworks.flat, $securityGroupName, $this.securityGroups)
- $.networks.customNetworks.select($this.joinNet($, $securityGroupName, $this.securityGroups))
- $preparedUserData: $.prepareUserData()
- $properties:
name: $.name
flavor: $.flavor
availability_zone: $.availabilityZone
user_data: $preparedUserData.data
user_data_format: $preparedUserData.format
key_name: $.keyname
metadata: $this.getMetadata($region)
- If: len($.blockDevices) > 0
Then:
- $bdmDefinition: $.blockDevices.select($this.buidBlockDeviceDefinition($))
- $properties.block_device_mapping_v2: $bdmDefinition
Else:
$properties.image: $.image
- If: $.instanceAffinityGroup != null
Then:
- $.instanceAffinityGroup.deploy()
- $properties.scheduler_hints:
group: $.instanceAffinityGroup.getRef()
- $template:
resources:
$.name:
type: $this.getResourceType()
properties: $properties
outputs:
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()
- For: blockDevice
In: $.blockDevices
Do:
- $blockDevice.volume.setAttachments($outputs.get(format('{0}-attachments', $blockDevice.volume.getResourceName())))
- $.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)})
- $.ipAddresses: $this.joinedNetworks.selectMany($.ipList).where($ != $this.floatingIpAddress).distinct()
- If: $.floatingIpAddress != null
Then:
- $.ipAddresses: $.ipAddresses.append($.floatingIpAddress)
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()
- securityGroups:
Contract: [$.string()]
Body:
- $primary: $net = $._primaryNetwork
- $assignFip: $primary and $.assignFloatingIp and not $.getAttr(fipAssigned, false)
- $sharedIps: []
- For: sharedIp
In: $.sharedIps
Do:
- If: $sharedIp.network = $net
Then:
- $sharedIps: $sharedIps.append($sharedIp)
- $joinResult: $net.joinInstance(
instance => $this,
securityGroupName => $securityGroupName,
securityGroups => $securityGroups,
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}-id'.format($.name)).concat($.getAttr(instanceOutputs, []))
- $template.outputs: $template.outputs.deleteAll($outputsToDelete)
- $region.stack.setTemplate($template)
_onReferencedResourceDelete:
Arguments:
- resource:
Contract: $.class(std:CloudResource).notNull()
Body:
- If: sys:GC.isDoomed($this)
Then:
- $.beginReleaseResources()
endReleaseResources:
Body:
- $region: $.getRegion()
- $template: $region.stack.current()
- If: $template.get(resources) and $template.get(outputs) and not sys:GC.isDoomed($region)
Then:
- $region.stack.push(async => true)
- $.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
getResourceType:
Body:
- Return: 'OS::Nova::Server'