
If the configuration of software component has not been changed, but a set of nodes in the server group has been modified, the component's default checkClusterIsConfigured method will now properly return true, thus the configuration will be applied on newly added nodes. This is achieved by storing instance ids as part of component's 'configuration' attributed stored for its server group. Change-Id: Ic8bbddc577518071d90a6e33518156047a1d2e2e Closes-bug: #1634206
441 lines
13 KiB
YAML
441 lines
13 KiB
YAML
Namespaces:
|
|
=: io.murano.applications
|
|
std: io.murano
|
|
res: io.murano.resources
|
|
m: io.murano.metadata.engine
|
|
|
|
--- # ------------------------------------------------------------------ # ---
|
|
|
|
Name: Installable
|
|
|
|
Properties:
|
|
allowedInstallFailures:
|
|
Contract: $.string().notNull().check($ in ['none', 'one', 'two', 'three', 'any', 'quorum'])
|
|
Default: 'none'
|
|
|
|
beforeInstallEvent:
|
|
Contract: $.class(Event).notNull()
|
|
Usage: Runtime
|
|
Default:
|
|
name: beforeInstall
|
|
|
|
installServerEvent:
|
|
Contract: $.class(Event).notNull()
|
|
Usage: Runtime
|
|
Default:
|
|
name: installServer
|
|
|
|
completeInstallationEvent:
|
|
Contract: $.class(Event).notNull()
|
|
Usage: Runtime
|
|
Default:
|
|
name: completeInstallation
|
|
|
|
Methods:
|
|
install:
|
|
Arguments:
|
|
- serverGroup:
|
|
Contract: $.class(ServerGroup).notNull()
|
|
Body:
|
|
- $serversToInstall: $serverGroup.getServers().pselect(
|
|
switch($this.checkServerIsInstalled($) => null, true => $)).where($ != null)
|
|
- If: any($serversToInstall)
|
|
Then:
|
|
- $.beforeInstall($serversToInstall, $serverGroup)
|
|
- $failures: $serversToInstall.pselect($this.installServer($, $serverGroup)).where($ != null)
|
|
- $.completeInstallation($serversToInstall, $serverGroup, $failures)
|
|
|
|
checkServerIsInstalled:
|
|
Meta:
|
|
- m:Synchronize:
|
|
onArgs: server
|
|
Arguments:
|
|
- server:
|
|
Contract: $.class(res:Instance)
|
|
Body:
|
|
- Return: $server.getAttr(installed, false)
|
|
|
|
beforeInstall:
|
|
Arguments:
|
|
- servers:
|
|
Contract:
|
|
- $.class(res:Instance).notNull()
|
|
- serverGroup:
|
|
Contract: $.class(ServerGroup).notNull()
|
|
Body:
|
|
- $this.report(format('Installing {0}', name($this)))
|
|
- $this.beforeInstallEvent.notify($this, $servers, $serverGroup)
|
|
- $this.onBeforeInstall($servers, $serverGroup)
|
|
|
|
onBeforeInstall:
|
|
Arguments:
|
|
- servers:
|
|
Contract:
|
|
- $.class(res:Instance).notNull()
|
|
- serverGroup:
|
|
Contract: $.class(ServerGroup).notNull()
|
|
|
|
installServer:
|
|
Meta:
|
|
- m:Synchronize:
|
|
onArgs: server
|
|
Arguments:
|
|
- server:
|
|
Contract: $.class(res:Instance).notNull()
|
|
- serverGroup:
|
|
Contract: $.class(ServerGroup).notNull()
|
|
Body:
|
|
Try:
|
|
- $this.report(format('Began installing {0} on {1}', name($this),
|
|
$server.name))
|
|
- $this.installServerEvent.notify($this, $server, $serverGroup)
|
|
- $this.onInstallServer($server, $serverGroup)
|
|
|
|
Catch:
|
|
- As: e
|
|
Do:
|
|
- $this.report(format('Unable to install {0} on {1} due to {2}',
|
|
name($this), $server.name, $e.message))
|
|
- Return: $server
|
|
Else:
|
|
- $this.report(format('{0} is installed on {1}',
|
|
name($this),
|
|
$server.name))
|
|
- $server.setAttr(installed, true)
|
|
- Return: null
|
|
|
|
onInstallServer:
|
|
Meta:
|
|
- m:Synchronize:
|
|
onArgs: server
|
|
Arguments:
|
|
- server:
|
|
Contract: $.class(res:Instance).notNull()
|
|
- serverGroup:
|
|
Contract: $.class(ServerGroup).notNull()
|
|
|
|
completeInstallation:
|
|
Arguments:
|
|
- servers:
|
|
Contract:
|
|
- $.class(res:Instance).notNull()
|
|
- serverGroup:
|
|
Contract: $.class(ServerGroup).notNull()
|
|
- failedServers:
|
|
Contract:
|
|
- $.class(res:Instance).notNull()
|
|
Body:
|
|
- $success: :SoftwareComponent.detectSuccess($this.allowedInstallFailures, $serverGroup, $failedServers)
|
|
- If: $success
|
|
Then:
|
|
- $this.completeInstallationEvent.notify($this, $servers, $serverGroup, $failedServers)
|
|
- $this.onCompleteInstallation($servers, $serverGroup, $failedServers)
|
|
|
|
- $this.report(format('Finished installing {0} ({1} errors encountered)',
|
|
name($this), len($failedServers) or 'no'))
|
|
Else:
|
|
- Throw: TooManyInstallationErrors
|
|
Message: format('Too many errors ({0}) encountered while installing {1}',
|
|
len($failedServers), name($this))
|
|
|
|
onCompleteInstallation:
|
|
Arguments:
|
|
- servers:
|
|
Contract:
|
|
- $.class(res:Instance).notNull()
|
|
- serverGroup:
|
|
Contract: $.class(ServerGroup).notNull()
|
|
- failedServers:
|
|
Contract:
|
|
- $.class(res:Instance).notNull()
|
|
|
|
report:
|
|
Arguments:
|
|
- message:
|
|
Contract: $.string().notNull()
|
|
Body:
|
|
- $env: $this.find(std:Environment)
|
|
- If: $env
|
|
Then:
|
|
- $env.reporter.report($this, $message)
|
|
|
|
--- # ------------------------------------------------------------------ # ---
|
|
|
|
Name: Configurable
|
|
|
|
Properties:
|
|
allowedConfigurationFailures:
|
|
Contract: $.string().notNull().check($ in ['none', 'one', 'two', 'three', 'any', 'quorum'])
|
|
Default: 'none'
|
|
|
|
preConfigureEvent:
|
|
Contract: $.class(Event).notNull()
|
|
Usage: Runtime
|
|
Default:
|
|
name: preConfigure
|
|
|
|
configureServerEvent:
|
|
Contract: $.class(Event).notNull()
|
|
Usage: Runtime
|
|
Default:
|
|
name: configureServer
|
|
|
|
completeConfigurationEvent:
|
|
Contract: $.class(Event).notNull()
|
|
Usage: Runtime
|
|
Default:
|
|
name: completeConfiguration
|
|
|
|
Methods:
|
|
.init:
|
|
Body:
|
|
- $this._randomName: randomName()
|
|
|
|
configure:
|
|
Arguments:
|
|
- serverGroup:
|
|
Contract: $.class(ServerGroup).notNull()
|
|
Body:
|
|
- If: $this.checkClusterIsConfigured($serverGroup)
|
|
Then:
|
|
- Return:
|
|
- $serversToConfigure: $serverGroup.getServers().pselect(
|
|
switch($this.checkServerIsConfigured($, $serverGroup) => null, true => $)).where($ != null)
|
|
- $this.preConfigure($serversToConfigure, $serverGroup)
|
|
- $failures: $serversToConfigure.pselect($this.configureServer($, $serverGroup)).where($ != null)
|
|
- $.completeConfiguration($serversToConfigure, $serverGroup, $failures)
|
|
|
|
checkClusterIsConfigured:
|
|
Arguments:
|
|
- serverGroup:
|
|
Contract: $.class(ServerGroup).notNull()
|
|
Body:
|
|
- $key: list($this.getConfigurationKey()) + $serverGroup.getKey()
|
|
- $state: $serverGroup.getAttr(configuration)
|
|
- Return: $key = $state
|
|
|
|
checkServerIsConfigured:
|
|
Meta:
|
|
- m:Synchronize:
|
|
onArgs: server
|
|
Arguments:
|
|
- server:
|
|
Contract: $.class(res:Instance).notNull()
|
|
- serverGroup:
|
|
Contract: $.class(ServerGroup).notNull()
|
|
Body:
|
|
- $key: $this.getConfigurationKey()
|
|
- $state: $server.getAttr(configuration, null)
|
|
- Return: $key = $state
|
|
|
|
getConfigurationKey:
|
|
Body:
|
|
# should be redefined in subclasses to contain semantical signature
|
|
# of the object's configuration
|
|
- Return: $this._randomName
|
|
|
|
preConfigure:
|
|
Arguments:
|
|
- servers:
|
|
Contract:
|
|
- $.class(res:Instance).notNull()
|
|
- serverGroup:
|
|
Contract: $.class(ServerGroup).notNull()
|
|
Body:
|
|
- $this.report(format('Applying configuration of {0}', name($this)))
|
|
- $this.configureSecurity($servers, $serverGroup)
|
|
- $this.preConfigureEvent.notify($this, $servers, $serverGroup)
|
|
- $this.onPreConfigure($servers, $serverGroup)
|
|
|
|
configureSecurity:
|
|
Arguments:
|
|
- servers:
|
|
Contract:
|
|
- $.class(res:Instance).notNull()
|
|
- serverGroup:
|
|
Contract: $.class(ServerGroup).notNull()
|
|
|
|
onPreConfigure:
|
|
Arguments:
|
|
- servers:
|
|
Contract:
|
|
- $.class(res:Instance).notNull()
|
|
- serverGroup:
|
|
Contract: $.class(ServerGroup).notNull()
|
|
|
|
configureServer:
|
|
Meta:
|
|
- m:Synchronize:
|
|
onArgs: server
|
|
Arguments:
|
|
- server:
|
|
Contract: $.class(res:Instance).notNull()
|
|
- serverGroup:
|
|
Contract: $.class(ServerGroup).notNull()
|
|
Body:
|
|
- Try:
|
|
- $this.report(format('Began configuring {0} on {1}',
|
|
name($this), $server.name))
|
|
- $this.configureServerEvent.notify($this, $server, $serverGroup)
|
|
- $this.onConfigureServer($server, $serverGroup)
|
|
|
|
Catch:
|
|
- As: e
|
|
Do:
|
|
- $this.report(format('Unable to configure {0} on {1} due to {2}',
|
|
name($this), $server.name, $e.message))
|
|
- Return: $server
|
|
Else:
|
|
- $key: $this.getConfigurationKey()
|
|
- $server.setAttr(configuration, $key)
|
|
- $this.report(format('{0} is configured at {1}', name($this), $server.name))
|
|
- Return: null
|
|
|
|
onConfigureServer:
|
|
Meta:
|
|
- m:Synchronize:
|
|
onArgs: server
|
|
Arguments:
|
|
- server:
|
|
Contract: $.class(res:Instance).notNull()
|
|
- serverGroup:
|
|
Contract: $.class(ServerGroup).notNull()
|
|
|
|
completeConfiguration:
|
|
Arguments:
|
|
- servers:
|
|
Contract:
|
|
- $.class(res:Instance).notNull()
|
|
- serverGroup:
|
|
Contract: $.class(ServerGroup).notNull()
|
|
- failedServers:
|
|
Contract:
|
|
- $.class(res:Instance).notNull()
|
|
Body:
|
|
- $success: :SoftwareComponent.detectSuccess($this.allowedConfigurationFailures, $serverGroup, $failedServers)
|
|
- If: $success
|
|
Then:
|
|
- $this.completeConfigurationEvent.notify($this, $servers, $serverGroup, $failedServers)
|
|
- $this.onCompleteConfiguration($servers, $serverGroup, $failedServers)
|
|
- $key: list($this.getConfigurationKey()) + $serverGroup.getKey()
|
|
- $serverGroup.setAttr(configuration, $key)
|
|
- $this.report(format('Finished configuring {0} ({1} errors encountered)',
|
|
name($this), $numFailures or 'no'))
|
|
Else:
|
|
- Throw: TooManyConfigurationErrors
|
|
Message: format('Too many errors ({0}) encountered while configuring {1}',
|
|
$numFailures, name($this))
|
|
|
|
onCompleteConfiguration:
|
|
Arguments:
|
|
- servers:
|
|
Contract:
|
|
- $.class(res:Instance).notNull()
|
|
- serverGroup:
|
|
Contract: $.class(ServerGroup).notNull()
|
|
- failedServers:
|
|
Contract:
|
|
- $.class(res:Instance).notNull()
|
|
|
|
report:
|
|
Arguments:
|
|
- message:
|
|
Contract: $.string().notNull()
|
|
Body:
|
|
- $env: $this.find(std:Environment)
|
|
- If: $env
|
|
Then:
|
|
- $env.reporter.report($this, $message)
|
|
|
|
--- # ------------------------------------------------------------------ # ---
|
|
|
|
Name: OpenStackSecurityConfigurable
|
|
Extends: Configurable
|
|
|
|
Methods:
|
|
configureSecurity:
|
|
Arguments:
|
|
- servers:
|
|
Contract:
|
|
- $.class(res:Instance).notNull()
|
|
- serverGroup:
|
|
Contract: $.class(ServerGroup).notNull()
|
|
Body:
|
|
- $sr: $this.getSecurityRules()
|
|
- If: $sr
|
|
Then:
|
|
- $regions: $servers.select($.getRegion()).distinct()
|
|
- $regions.pselect($this._configureSecurityGroup($, $sr))
|
|
|
|
_configureSecurityGroup:
|
|
Usage: Static
|
|
Arguments:
|
|
- region:
|
|
Contract: $.class(std:CloudRegion).notNull()
|
|
- rules:
|
|
Contract:
|
|
- FromPort: $.int().notNull()
|
|
ToPort: $.int().notNull()
|
|
IpProtocol: $.string().notNull()
|
|
External: $.bool().notNull()
|
|
Ethertype: $.string().check($ in list(null, 'IPv4', 'IPv6'))
|
|
Body:
|
|
- $region.securityGroupManager.addGroupIngress($rules)
|
|
- $region.stack.push()
|
|
|
|
getSecurityRules:
|
|
Body:
|
|
- Return: {}
|
|
|
|
--- # ------------------------------------------------------------------ # ---
|
|
Name: SoftwareComponent
|
|
Extends:
|
|
- Installable
|
|
- Configurable
|
|
|
|
Methods:
|
|
deployAt:
|
|
Arguments:
|
|
- serverGroup:
|
|
Contract: $.class(ServerGroup).notNull()
|
|
Body:
|
|
- $serverGroup.deploy()
|
|
- $this.install($serverGroup)
|
|
- $this.configure($serverGroup)
|
|
|
|
report:
|
|
Arguments:
|
|
- message:
|
|
Contract: $.string().notNull()
|
|
Body:
|
|
- cast($this, Installable).report($message)
|
|
|
|
detectSuccess:
|
|
Usage: Static
|
|
Arguments:
|
|
- allowedFailures:
|
|
Contract: $.string().notNull().check($ in ['none', 'one', 'two', 'three', 'any', 'quorum'])
|
|
- serverGroup:
|
|
Contract: $.class(ServerGroup).notNull()
|
|
- failedServers:
|
|
Contract:
|
|
- $.class(res:Instance).notNull()
|
|
Body:
|
|
- $numFailures: len($failedServers)
|
|
- Match:
|
|
none:
|
|
- Return: $numFailures = 0
|
|
one:
|
|
- Return: $numFailures <= 1
|
|
two:
|
|
- Return: $numFailures <= 2
|
|
three:
|
|
- Return: $numFailures <= 3
|
|
any:
|
|
- Return: true
|
|
quorum:
|
|
- $numServers: $serverGroup.getServers().count()
|
|
- $maxFailures: $numServers - ($numServers/2 + 1)
|
|
- Return: $numFailures <= $maxFailures
|
|
Value: $allowedFailures
|