Namespaces: =: io.murano.apps.docker.kubernetes std: io.murano res: io.murano.resources sys: io.murano.system docker: io.murano.apps.docker Name: KubernetesCluster Extends: std:Application Properties: name: Contract: $.string().notNull() masterNode: Contract: $.class(KubernetesMasterNode).notNull() minionNodes: Contract: - $.class(KubernetesMinionNode).notNull() - 1 nodeCount: Contract: $.int().notNull().check($ > 0) gatewayCount: Contract: $.int().notNull() gatewayNodes: Contract: - $.class(KubernetesGatewayNode).notNull() serviceEndpoints: Contract: - port: $.int().notNull().check($ > 0) address: $.string().notNull() scope: $.string().notNull().check($ in list(public, cloud, internal)) applicationPort: $.class(docker:ApplicationPort).notNull() applicationName: $.string().notNull() podId: $.string().notNull() name: $.string().notNull() Default: [] Usage: Out Methods: initialize: Body: - $._environment: $.find(std:Environment).require() - $._services: {} - For: endpoint In: $.serviceEndpoints Do: - $port: $endpoint.port - $._services[$port]: applicationName: $endpoint.applicationName applicationPort: $endpoint.applicationPort podId: $endpoint.podId name: $endpoint.name deploy: Body: - If: not $.getAttr(deployed, false) Then: - $._environment.reporter.report($this, 'Creating VMs for Kubernetes cluster') - $securityGroupIngress: - ToPort: 4001 FromPort: 4001 IpProtocol: tcp External: false - ToPort: 7001 FromPort: 7001 IpProtocol: tcp External: false - ToPort: 10250 FromPort: 10250 IpProtocol: tcp External: false - ToPort: 8080 FromPort: 8080 IpProtocol: tcp External: false - ToPort: 2380 FromPort: 2380 IpProtocol: tcp External: false - ToPort: 8285 FromPort: 8285 IpProtocol: udp External: false - $._environment.securityGroupManager.addGroupIngress($securityGroupIngress) - $.setAttr(deployed, true) - $._environment.reporter.report($this, 'Setting up Kubernetes cluster') - Parallel: - Do: $.masterNode.deployInstance() - Do: $.minionNodes.take($.nodeCount).pselect($.deployInstance()) - Do: $.gatewayNodes.take($.gatewayCount).pselect($.deployInstance()) - $.masterNode.setupEtcd() - $.minionNodes.take($.nodeCount).select($.setupEtcd()) - $.gatewayNodes.take($.gatewayCount).select($.setupEtcd()) - $.masterNode.setupNode() - Parallel: - Do: $.minionNodes.take($.nodeCount).pselect($.setupNode()) - Do: $.minionNodes.skip($.nodeCount).pselect($.removeFromCluster()) - Do: $.gatewayNodes.take($.gatewayCount).pselect($.setupNode()) - $._deployServices() getIp: Body: Return: $.masterNode.getIp() createPod: Arguments: - definition: Contract: {} - isNew: Contract: $.bool().notNull() Default: true Body: - $.deploy() - $resources: new(sys:Resources) - $template: $resources.yaml('UpdatePod.template').bind(dict( podDefinition => $definition, isNew => $isNew )) - $.masterNode.instance.agent.call($template, $resources) createReplicationController: Arguments: - definition: Contract: {} - isNew: Contract: $.bool().notNull() Default: true Body: - $.deploy() - $resources: new(sys:Resources) - $template: $resources.yaml('UpdateReplicationController.template').bind(dict( controllerDefinition => $definition, isNew => $isNew )) - $.masterNode.instance.agent.call($template, $resources) destroyReplicationController: Arguments: - id: Contract: $.string().notNull() Body: - $.deploy() - $resources: new(sys:Resources) - $template: $resources.yaml('DestroyReplicationController.template').bind(dict(rcId => $id)) - $.kubernetesCluster.masterNode.instance.agent.call($template, $resources) createServices: Arguments: - applicationName: Contract: $.string().notNull() - applicationPorts: Contract: - $.class(docker:ApplicationPort) - podId: Contract: $.string().notNull() Body: - $._destroyService($applicationName, $podId) - For: applicationPort In: $applicationPorts.where($.scope in list(public, host)) Do: - $allocatedPort: $._findUnusedPort($applicationPort.port) - $._services[$allocatedPort]: applicationName: $applicationName applicationPort: $applicationPort podId: $podId name: format('svc-{0}', randomName()) - $.deploy() _destroyService: Arguments: - applicationName: Contract: $.string().notNull() - podId: Contract: $.string().notNull() Body: - $services: {} - For: port In: $._services.keys() Do: - $record: $._services.get($port) - If: $record.applicationName != $applicationName or $record.podId != $podId Then: $services[$port]: $record - $._services: $services destroyService: Arguments: - applicationName: Contract: $.string().notNull() - podId: Contract: $.string().notNull() Body: - $._destroyService($applicationName, $podId) - $.deploy() _deployServices: Body: - $services: $._services - $endpoints: [] - $skipPorts: [] - $resources: new(sys:Resources) - $prevNodeCount: $.getAttr(lastNodeCount, -1) - $prevGatewayCount: $.getAttr(lastGatewayCount, -1) - $gatewayModeChanged: $prevGatewayCount != $.gatewayCount and $prevGatewayCount * $.gatewayCount = 0 - $serviceEndpoints: {} - For: deployedRecord In: $.serviceEndpoints.where($.scope = cloud) Do: - $port: $deployedRecord.port - If: not $port in $services.keys() Then: - $template: $resources.yaml('DestroyService.template').bind(dict( serviceId => $deployedRecord.name )) - $.masterNode.instance.agent.call($template, $resources) Else: $serviceEndpoints[$port]: $deployedRecord - For: port In: $services.keys() Do: - $runtimeRecord: $services.get($port) - $deployedRecord: $serviceEndpoints.get($port) - $portChanged: $deployedRecord = null - If: not $portChanged Then: $portChanged: $deployedRecord.podId != $runtimeRecord.podId or $runtimeRecord.applicationPort.scope = public and ( $gatewayModeChanged or $.gatewayCount = 0 and $prevNodeCount != nodeCount) - If: $portChanged Then: - $serviceDefinition: $._buildServiceDefinition( $runtimeRecord.name, $port, $runtimeRecord.applicationPort.port, $runtimeRecord.podId, $.gatewayCount = 0 ) - $template: $resources.yaml('UpdateService.template').bind(dict( serviceDefinition => $serviceDefinition, isNew => $deployedRecord = null )) - If: $runtimeRecord.applicationPort.scope = public Then: - $securityGroupIngress: - ToPort: $port FromPort: $port IpProtocol: toLower($runtimeRecord.applicationPort.protocol) External: true - $._environment.securityGroupManager.addGroupIngress($securityGroupIngress) - $serviceIp: $.masterNode.instance.agent.call($template, $resources) Else: - $serviceIp: $deployedRecord.address - $endpoint: port: $port address: $serviceIp scope: internal applicationPort: $runtimeRecord.applicationPort applicationName: $runtimeRecord.applicationName podId: $runtimeRecord.podId name: $runtimeRecord.name - $endpoints: $endpoints + list($endpoint) - If: $runtimeRecord.applicationPort.scope = public Then: - If: $.gatewayCount > 0 Then: $nodes: $.gatewayNodes.take($.gatewayCount) Else: $nodes: $.minionNodes.take($.nodeCount) - For: t In: $nodes Do: - $endpoint.address: $t.getIp() - $endpoint.scope: cloud - $endpoints: $endpoints + list($endpoint) - If: $t.instance.floatingIpAddress != null Then: - $endpoint.address: $t.instance.floatingIpAddress - $endpoint.scope: public - $endpoints: $endpoints + list($endpoint) - $.serviceEndpoints: $endpoints - $._environment.stack.push() _findUnusedPort: Arguments: - initial: Contract: $.int().notNull() Body: - If: not $initial in $._services.keys() Then: Return: $initial - $port: 1025 - While: $port in $._services.keys() Do: $port: $port + 1 - Return: $port _buildServiceDefinition: Arguments: - serviceName: Contract: $.string().notNull() - servicePort: Contract: $.int().notNull() - containerPort: Contract: $.int().notNull() - podId: Contract: $.string().notNull() - withDodeIps: Contract: $.bool().notNull() Body: - $result: id: $serviceName kind: Service apiVersion: v1beta1 port: $servicePort containerPort: $containerPort selector: id: $podId - If: $withDodeIps Then: - $result.publicIPs: $.minionNodes.take($.nodeCount).select($.getIp()) - Return: $result scaleUp: Usage: Action Body: - If: $.nodeCount < len($.minionNodes) Then: - $._environment.reporter.report($this, 'Scaling up Kubernetes cluster') - $.nodeCount: $.nodeCount + 1 - $.deploy() scaleDown: Usage: Action Body: - If: $.nodeCount > 1 Then: - $._environment.reporter.report($this, 'Scaling Kubernetes cluster down') - $.nodeCount: $.nodeCount - 1 - $.deploy() scaleGatewaysUp: Usage: Action Body: - If: $.nodeCount < len($.gatewayNodes) Then: - $._environment.reporter.report($this, 'Adding new gateway node') - $.nodeCount: $.gatewayCount + 1 - $.deploy() scaleGatewaysUp: Usage: Action Body: - If: $.nodeCount > 0 Then: - $._environment.reporter.report($this, 'Removing gateway node') - $.nodeCount: $.gatewayCount - 1 - $.deploy() exportConfig: Usage: Action Body: - $._environment.reporter.report($this, 'Action exportConfig called') - $resources: new(sys:Resources) - $template: $resources.yaml('ExportConfig.template') - $result: $.masterNode.instance.agent.call($template, $resources) - $._environment.reporter.report($this, 'Got archive from Kubernetes') - Return: new(std:File, base64Content=>$result.content, filename => 'application.tar.gz')