hub-clusters-creator 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +5 -0
- data/Makefile +28 -0
- data/bin/aks.rb +42 -0
- data/bin/gke.rb +48 -0
- data/docker/Dockerfile +20 -0
- data/docker/entrypoint.sh +89 -0
- data/hub-clusters-creator.gemspec +34 -0
- data/lib/hub-clusters-creator.rb +49 -0
- data/lib/hub-clusters-creator/agent.rb +142 -0
- data/lib/hub-clusters-creator/errors.rb +48 -0
- data/lib/hub-clusters-creator/kube/kube.rb +147 -0
- data/lib/hub-clusters-creator/logging.rb +46 -0
- data/lib/hub-clusters-creator/providers/aks/azure.rb +272 -0
- data/lib/hub-clusters-creator/providers/aks/helpers.rb +105 -0
- data/lib/hub-clusters-creator/providers/aks/schema.yaml +125 -0
- data/lib/hub-clusters-creator/providers/bootstrap.rb +226 -0
- data/lib/hub-clusters-creator/providers/gke/gke.rb +264 -0
- data/lib/hub-clusters-creator/providers/gke/helpers.rb +364 -0
- data/lib/hub-clusters-creator/providers/gke/schema.yaml +411 -0
- data/lib/hub-clusters-creator/providers/schema.yaml +113 -0
- data/lib/hub-clusters-creator/template.rb +45 -0
- data/lib/hub-clusters-creator/version.rb +20 -0
- metadata +192 -0
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright (C) 2019 Rohith Jayawardene <gambol99@gmail.com>
|
4
|
+
#
|
5
|
+
# This program is free software; you can redistribute it and/or
|
6
|
+
# modify it under the terms of the GNU General Public License
|
7
|
+
# as published by the Free Software Foundation; either version 2
|
8
|
+
# of the License, or (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU General Public License
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
|
18
|
+
# rubocop:disable Metrics/LineLength
|
19
|
+
module HubClustersCreator
|
20
|
+
# Errors is collection of custom errors and exceptions
|
21
|
+
module Errors
|
22
|
+
# InfrastructureError defines an error occurred creating or configuring the cluster
|
23
|
+
class InfrastructureError < StandardError
|
24
|
+
def initialize(msg = 'failed attempting to create the cluster')
|
25
|
+
super(msg)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# ConfigurationError defines an error related to configuration
|
30
|
+
class ConfigurationError < StandardError
|
31
|
+
attr_accessor :field, :value
|
32
|
+
|
33
|
+
def initialize(msg = 'invalid configuration', field:, value:)
|
34
|
+
@field = field
|
35
|
+
@value = value
|
36
|
+
super(msg)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# InitializerError is thrown when we've encountered an error attempting to bootstrap cluster
|
41
|
+
class InitializerError < StandardError
|
42
|
+
def initialize(msg = 'failed attempting to bootstrap the cluster')
|
43
|
+
super(msg)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
# rubocop:enable Metrics/LineLength
|
@@ -0,0 +1,147 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright (C) 2019 Rohith Jayawardene <gambol99@gmail.com>
|
4
|
+
#
|
5
|
+
# This program is free software; you can redistribute it and/or
|
6
|
+
# modify it under the terms of the GNU General Public License
|
7
|
+
# as published by the Free Software Foundation; either version 2
|
8
|
+
# of the License, or (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU General Public License
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
|
18
|
+
require 'k8s-client'
|
19
|
+
|
20
|
+
module HubClustersCreator
|
21
|
+
# Kube is a collection of methods for interacting with the kubernetes api
|
22
|
+
# rubocop:disable Metrics/LineLength,Metrics/MethodLength,Metrics/ParameterLists
|
23
|
+
class Kube
|
24
|
+
attr_accessor :endpoint
|
25
|
+
|
26
|
+
def initialize(endpoint, token: nil, client_certificate: nil, client_key: nil, certificate_authority: nil)
|
27
|
+
options = {
|
28
|
+
ssl_verify_peer: false
|
29
|
+
}
|
30
|
+
|
31
|
+
config = K8s::Config.new(
|
32
|
+
clusters: [{
|
33
|
+
name: 'default',
|
34
|
+
cluster: { server: 'https://' + endpoint, certificate_authority_data: certificate_authority }
|
35
|
+
}],
|
36
|
+
users: [{
|
37
|
+
name: 'default',
|
38
|
+
user: {
|
39
|
+
token: token,
|
40
|
+
client_certificate_data: client_certificate,
|
41
|
+
client_key_data: client_key
|
42
|
+
}
|
43
|
+
}],
|
44
|
+
contexts: [{
|
45
|
+
name: 'default',
|
46
|
+
context: { cluster: 'default', user: 'default' }
|
47
|
+
}],
|
48
|
+
current_context: 'default'
|
49
|
+
)
|
50
|
+
|
51
|
+
@endpoint = "https://#{endpoint}" unless endpoint.start_with?('https')
|
52
|
+
@client = K8s::Client.config(config, options)
|
53
|
+
end
|
54
|
+
|
55
|
+
# exists? checks if the resource exists
|
56
|
+
def exists?(name, kind, namespace = 'default', version = 'v1')
|
57
|
+
begin
|
58
|
+
kind = "#{kind}s" unless kind.end_with?('s')
|
59
|
+
@client.api(version).resource(kind, namespace: namespace).get(name)
|
60
|
+
rescue K8s::Error::NotFound
|
61
|
+
return false
|
62
|
+
end
|
63
|
+
true
|
64
|
+
end
|
65
|
+
|
66
|
+
# get retrieves a resource from the cluster
|
67
|
+
def get(name, namespace, kind, version: 'v1')
|
68
|
+
@client.api(version).resource(kind, namespace: namespace).get(name)
|
69
|
+
end
|
70
|
+
|
71
|
+
# delete removes a resource from the cluster
|
72
|
+
def delete(name, kind, namespace, version: 'v1')
|
73
|
+
return unless exists?(name, kind, namespace, version)
|
74
|
+
|
75
|
+
@client.api(version).resource(kind, namespace: namespace).delete_resource(name)
|
76
|
+
end
|
77
|
+
|
78
|
+
# wait is used to poll until a resource meets the needs of the consumer
|
79
|
+
# rubocop:disable Lint/RescueException,Metrics/CyclomaticComplexity,Metrics/AbcSize
|
80
|
+
def wait(name, namespace, kind, version: 'v1', max_retries: 50, timeout: 300, interval: 5, &block)
|
81
|
+
retries = counter = 0
|
82
|
+
while counter < timeout
|
83
|
+
begin
|
84
|
+
unless block_given?
|
85
|
+
return if exists?(name, kind, namespace, version)
|
86
|
+
|
87
|
+
continue
|
88
|
+
end
|
89
|
+
|
90
|
+
resource = @client.api(version).resource(kind).get(name, namespace: namespace)
|
91
|
+
return if block.call(resource)
|
92
|
+
rescue Exception => e
|
93
|
+
raise e if retries > max_retries
|
94
|
+
|
95
|
+
retries += 1
|
96
|
+
end
|
97
|
+
sleep(interval)
|
98
|
+
counter += interval
|
99
|
+
end
|
100
|
+
|
101
|
+
raise Exception, "operation waiting for #{name}/#{namespace}/#{kind} has failed"
|
102
|
+
end
|
103
|
+
# rubocop:enable Lint/RescueException,Metrics/CyclomaticComplexity,Metrics/AbcSize
|
104
|
+
|
105
|
+
# kubectl is used to apply a manifest
|
106
|
+
# rubocop:disable Metrics/AbcSize
|
107
|
+
def kubectl(manifest)
|
108
|
+
resource = K8s::Resource.from_json(YAML.safe_load(manifest).to_json)
|
109
|
+
raise ArgumentError, 'no api version associated to resource' unless resource.apiVersion
|
110
|
+
raise ArgumentError, 'no kind associated to resource' unless resource.kind
|
111
|
+
raise ArgumentError, 'no metadata associated to resource' unless resource.metadata
|
112
|
+
raise ArgumentError, 'no name associated to resource' unless resource.metadata.name
|
113
|
+
|
114
|
+
name = resource.metadata.name
|
115
|
+
namespace = resource.metadata.namespace
|
116
|
+
kind = resource.kind.downcase
|
117
|
+
version = resource.apiVersion
|
118
|
+
return if exists?(name, kind, namespace, version)
|
119
|
+
|
120
|
+
@client.api(version).resource("#{kind}s", namespace: namespace).create_resource(resource)
|
121
|
+
end
|
122
|
+
# rubocop:enable Metrics/AbcSize
|
123
|
+
|
124
|
+
# account returns the credentials for a service account
|
125
|
+
def account(name, namespace = 'kube-system')
|
126
|
+
sa = @client.api('v1').resource('serviceaccounts', namespace: namespace).get(name)
|
127
|
+
secret = @client.api('v1').resource('secrets', namespace: namespace).get(sa.secrets.first.name)
|
128
|
+
secret.data.token
|
129
|
+
end
|
130
|
+
|
131
|
+
# wait_for_kubeapi is responsible for waiting the api is available
|
132
|
+
def wait_for_kubeapi(max_attempts = 60, interval = 5)
|
133
|
+
attempts = 0
|
134
|
+
while attempts < max_attempts
|
135
|
+
begin
|
136
|
+
return if @client.api('v1').resource('nodes').list
|
137
|
+
rescue StandardError => e
|
138
|
+
puts "bad: #{e}"
|
139
|
+
attempts += 1
|
140
|
+
end
|
141
|
+
sleep(interval)
|
142
|
+
end
|
143
|
+
raise Exception, 'timed out waiting for the kube api'
|
144
|
+
end
|
145
|
+
end
|
146
|
+
# rubocop:enable Metrics/LineLength,Metrics/MethodLength,Metrics/ParameterLists
|
147
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright (C) 2019 Rohith Jayawardene <gambol99@gmail.com>
|
4
|
+
#
|
5
|
+
# This program is free software; you can redistribute it and/or
|
6
|
+
# modify it under the terms of the GNU General Public License
|
7
|
+
# as published by the Free Software Foundation; either version 2
|
8
|
+
# of the License, or (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU General Public License
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
#
|
18
|
+
|
19
|
+
module HubClustersCreator
|
20
|
+
# Logging is few helper functions for logging
|
21
|
+
module Logging
|
22
|
+
def info(string, options = {})
|
23
|
+
print formatted_string("[info] #{dated_string(string)}", options)
|
24
|
+
end
|
25
|
+
|
26
|
+
def warn(string)
|
27
|
+
Kernel.warn formatted_string(string, symbol: '*')
|
28
|
+
end
|
29
|
+
|
30
|
+
def error(string)
|
31
|
+
Kernel.warn formatted_string(string, symbol: '!')
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def dated_string(string)
|
37
|
+
"[#{Time.now}] #{string}"
|
38
|
+
end
|
39
|
+
|
40
|
+
def formatted_string(string, options = {})
|
41
|
+
symbol = options[:symbol] || ''
|
42
|
+
string = string.to_s
|
43
|
+
"#{symbol}#{string}\n"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,272 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright (C) 2019 Rohith Jayawardene <gambol99@gmail.com>
|
4
|
+
#
|
5
|
+
# This program is free software; you can redistribute it and/or
|
6
|
+
# modify it under the terms of the GNU General Public License
|
7
|
+
# as published by the Free Software Foundation; either version 2
|
8
|
+
# of the License, or (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU General Public License
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
#
|
18
|
+
require 'hub-clusters-creator/providers/aks/helpers'
|
19
|
+
require 'hub-clusters-creator/providers/bootstrap'
|
20
|
+
require 'hub-clusters-creator/template'
|
21
|
+
|
22
|
+
require 'azure_mgmt_resources'
|
23
|
+
require 'azure_mgmt_container_service'
|
24
|
+
require 'azure_mgmt_dns'
|
25
|
+
require 'uri'
|
26
|
+
|
27
|
+
# rubocop:disable Metrics/ClassLength,Metrics/LineLength,Metrics/MethodLength
|
28
|
+
module HubClustersCreator
|
29
|
+
module Providers
|
30
|
+
# AKS is the AKS provider
|
31
|
+
class AKS
|
32
|
+
include ::Azure::Resources::Profiles::Latest::Mgmt
|
33
|
+
include ::Azure::Resources::Profiles::Latest::Mgmt::Models
|
34
|
+
include ::Azure::ContainerService::Mgmt::V2019_04_01
|
35
|
+
include ::Azure::Dns::Mgmt::V2017_10_01
|
36
|
+
include Azure::Helpers
|
37
|
+
include HubClustersCreator::Utils::Template
|
38
|
+
include Errors
|
39
|
+
include Logging
|
40
|
+
|
41
|
+
# rubocop:disable Metrics/AbcSize
|
42
|
+
def initialize(provider)
|
43
|
+
%i[client_id client_secret region subscription tenant].each do |x|
|
44
|
+
raise ArgumentError, "you must specify the '#{x}' provider option" unless provider.key?(x)
|
45
|
+
end
|
46
|
+
|
47
|
+
@subscription = provider[:subscription]
|
48
|
+
@tenant = provider[:tenant]
|
49
|
+
@client_id = provider[:client_id]
|
50
|
+
@client_secret = provider[:client_secret]
|
51
|
+
@region = provider[:region]
|
52
|
+
|
53
|
+
@provider = MsRestAzure::ApplicationTokenProvider.new(@tenant, @client_id, @client_secret)
|
54
|
+
@credentials = MsRest::TokenCredentials.new(@provider)
|
55
|
+
|
56
|
+
@containers = ::Azure::ContainerService::Mgmt::V2019_04_01::ContainerServiceClient.new(@credentials)
|
57
|
+
@containers.subscription_id = @subscription
|
58
|
+
|
59
|
+
@dns = ::Azure::Dns::Mgmt::V2017_10_01::DnsManagementClient.new(@credentials)
|
60
|
+
@dns.subscription_id = @subscription
|
61
|
+
|
62
|
+
options = {
|
63
|
+
client_id: @client_id,
|
64
|
+
client_secret: @client_secret,
|
65
|
+
credentials: @credentials,
|
66
|
+
subscription_id: @subscription,
|
67
|
+
tenant_id: @tenant
|
68
|
+
}
|
69
|
+
|
70
|
+
@client = Client.new(options)
|
71
|
+
end
|
72
|
+
# rubocop:enable Metrics/AbcSize
|
73
|
+
|
74
|
+
# create is responsible for creating the cluster
|
75
|
+
def create(name, config)
|
76
|
+
# @step: validate the user defined options
|
77
|
+
validate(config)
|
78
|
+
|
79
|
+
# @step: create the infrastructure deployment
|
80
|
+
begin
|
81
|
+
provision_aks(name, config)
|
82
|
+
rescue StandardError => e
|
83
|
+
raise InfrastructureError, "failed to provision cluster, error: #{e}"
|
84
|
+
end
|
85
|
+
|
86
|
+
# @step: bootstrap the cluster
|
87
|
+
begin
|
88
|
+
provision_cluster(name, config)
|
89
|
+
rescue StandardError => e
|
90
|
+
raise InfrastructureError, "failed to bootstrap cluster, error: #{e}"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# delete is responsible for deleting the cluster via resource group
|
95
|
+
def delete(name)
|
96
|
+
return unless resource_group?(name)
|
97
|
+
|
98
|
+
info "deleting the resource group: #{name}"
|
99
|
+
@client.resource_groups.delete(name, name)
|
100
|
+
end
|
101
|
+
|
102
|
+
private
|
103
|
+
|
104
|
+
# provision_aks is responsible for provision the infrastructure
|
105
|
+
# rubocop:disable Metrics/AbcSize
|
106
|
+
def provision_aks(name, config)
|
107
|
+
# @step: define the resource group
|
108
|
+
resource_group_name = name
|
109
|
+
|
110
|
+
# @step: check the resource group exists
|
111
|
+
if resource_group?(resource_group_name)
|
112
|
+
info "skipping the resource group creation: #{resource_group_name}, already exists"
|
113
|
+
else
|
114
|
+
info "creating the resource group: #{resource_group_name} in azure"
|
115
|
+
params = ::Azure::Resources::Mgmt::V2019_05_10::Models::ResourceGroup.new.tap do |x|
|
116
|
+
x.location = @region
|
117
|
+
end
|
118
|
+
# ensure the resource group is created
|
119
|
+
@client.resource_groups.create_or_update(resource_group_name, params)
|
120
|
+
|
121
|
+
# wait for the resource group to be created
|
122
|
+
wait(max_retries: 20, interval: 10) do
|
123
|
+
resource_group?(resource_group_name)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
info "provisioning the azure deployment manifest: '#{name}', resource group: '#{resource_group_name}'"
|
128
|
+
# @step: generate the ARM deployments
|
129
|
+
template = YAML.safe_load(cluster_template(config))
|
130
|
+
|
131
|
+
# @step: check if a deployment is already underway and wait for completion - which
|
132
|
+
# makes it eaisier to rerun quickly
|
133
|
+
if deployment?(resource_group_name, name)
|
134
|
+
info "deployment: #{name}, resource group: #{resource_group_name} already underway, waiting for completion"
|
135
|
+
wait(interval: 30, max_retries: 20) do
|
136
|
+
if deployment?(resource_group_name, name)
|
137
|
+
d = deployment(resource_group_name, name)
|
138
|
+
d.properties.provisioning_state == 'Succeeded'
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
# @step: kick off the deployment and cross fingers
|
144
|
+
deployment = ::Azure::Resources::Mgmt::V2019_05_10::Models::Deployment.new
|
145
|
+
deployment.properties = ::Azure::Resources::Mgmt::V2019_05_10::Models::DeploymentProperties.new
|
146
|
+
deployment.properties.template = template
|
147
|
+
deployment.properties.mode = ::Azure::Resources::Mgmt::V2019_05_10::Models::DeploymentMode::Incremental
|
148
|
+
|
149
|
+
# put the deployment to the resource group
|
150
|
+
@client.deployments.create_or_update_async(resource_group_name, name, deployment)
|
151
|
+
# wait for the deployment to finish
|
152
|
+
wait(interval: 30, max_retries: 20) do
|
153
|
+
if deployment?(resource_group_name, name)
|
154
|
+
d = deployment(resource_group_name, name)
|
155
|
+
d.properties.provisioning_state == 'Succeeded'
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
# rubocop:enable Metrics/AbcSize
|
160
|
+
|
161
|
+
# provision_cluster is responsible for kicking off the initialization
|
162
|
+
# rubocop:disable Metrics/AbcSize
|
163
|
+
def provision_cluster(name, config)
|
164
|
+
resource_group_name = name
|
165
|
+
|
166
|
+
# @step retrieve the kubeconfig - I HATE everything about Azure!!
|
167
|
+
packed = @containers.managed_clusters.list_cluster_admin_credentials(resource_group_name, name)
|
168
|
+
kc = YAML.safe_load(packed.kubeconfigs.first.value.pack('c*'))
|
169
|
+
|
170
|
+
ca = kc['clusters'].first['cluster']['certificate-authority-data']
|
171
|
+
endpoint = URI(kc['clusters'].first['cluster']['server']).hostname
|
172
|
+
|
173
|
+
# @step: provision a kubernetes client for this cluster
|
174
|
+
kube = HubClustersCreator::Kube.new(endpoint,
|
175
|
+
client_certificate: kc['users'].first['user']['client-certificate-data'],
|
176
|
+
client_key: kc['users'].first['user']['client-key-data'])
|
177
|
+
|
178
|
+
info "waiting for the kubeapi to become available at: #{endpoint}"
|
179
|
+
kube.wait_for_kubeapi
|
180
|
+
|
181
|
+
# @step: provision the bootstrap
|
182
|
+
info "attempting to bootstrap the cluster: #{name}"
|
183
|
+
HubClustersCreator::Providers::Bootstrap.new(name, kube, config).bootstrap
|
184
|
+
|
185
|
+
# @step: update the dns record for the ingress
|
186
|
+
unless (config[:grafana_hostname] || '').empty?
|
187
|
+
# Get the ingress resource and extract the load balancer ip address
|
188
|
+
ingress = @client.get('loki-grafana', 'loki', 'ingresses', version: 'extensions/v1beta1')
|
189
|
+
|
190
|
+
unless ingress.status.loadBalancer.ingress.empty?
|
191
|
+
address = ingress.status.loadBalancer.ingress.first.ip
|
192
|
+
info "adding a dns record for #{config[:grafana_hostname]} => #{address}"
|
193
|
+
dns(hostname(config[:grafana_hostname]), address, config[:domain])
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
{
|
198
|
+
cluster: {
|
199
|
+
ca: ca,
|
200
|
+
endpoint: "https://#{endpoint}",
|
201
|
+
token: kube.account('sysadmin')
|
202
|
+
},
|
203
|
+
config: config,
|
204
|
+
services: {
|
205
|
+
grafana: {
|
206
|
+
hostname: config[:grafana_hostname]
|
207
|
+
}
|
208
|
+
}
|
209
|
+
}
|
210
|
+
end
|
211
|
+
# rubocop:enable Metrics/AbcSize
|
212
|
+
|
213
|
+
# validate is responsible for validating the options
|
214
|
+
def validate(options); end
|
215
|
+
|
216
|
+
# cluster_template is responsible for rendering the template for ARM
|
217
|
+
def cluster_template(config)
|
218
|
+
template = <<~YAML
|
219
|
+
'$schema': https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#
|
220
|
+
contentVersion: 1.0.0.0
|
221
|
+
parameters: {}
|
222
|
+
variables: {}
|
223
|
+
resources:
|
224
|
+
- type: Microsoft.ContainerService/managedClusters
|
225
|
+
name: <%= context[:name] %>
|
226
|
+
apiVersion: '2019-06-01'
|
227
|
+
location: #{@region}
|
228
|
+
tags:
|
229
|
+
cluster: <%= context[:name] %>
|
230
|
+
properties:
|
231
|
+
kubernetesVersion: <%= context[:version] %>
|
232
|
+
dnsPrefix: <%= context[:name] %>
|
233
|
+
addonProfiles:
|
234
|
+
httpapplicationrouting:
|
235
|
+
enabled: true
|
236
|
+
config:
|
237
|
+
HTTPApplicationRoutingZoneName: <%= context[:domain] %>
|
238
|
+
agentPoolProfiles:
|
239
|
+
- name: compute
|
240
|
+
count: <%= context[:size] %>
|
241
|
+
maxPods: 110
|
242
|
+
osDiskSizeGB: <%= context[:disk_size_gb] %>
|
243
|
+
osType: Linux
|
244
|
+
storageProfile: ManagedDisks
|
245
|
+
type: VirtualMachineScaleSets
|
246
|
+
vmSize: <%= context[:machine_type] %>
|
247
|
+
servicePrincipalProfile:
|
248
|
+
clientId: #{@client_id}
|
249
|
+
secret: #{@client_secret}
|
250
|
+
linuxProfile:
|
251
|
+
adminUsername: azureuser
|
252
|
+
<%- unless (context[:ssh_key] || '').empty? -%>
|
253
|
+
ssh:
|
254
|
+
publicKeys:
|
255
|
+
- keyData: <%= context[:ssh_key] %>
|
256
|
+
<%- end -%>
|
257
|
+
enableRBAC: true
|
258
|
+
enablePodSecurityPolicy: true
|
259
|
+
networkProfile:
|
260
|
+
dnsServiceIP: 10.0.0.10
|
261
|
+
dockerBridgeCidr: 172.17.0.1/16
|
262
|
+
loadBalancerSku: basic
|
263
|
+
networkPlugin: azure
|
264
|
+
networkPolicy: azure
|
265
|
+
serviceCidr: <%= context[:services_ipv4_cidr].empty? ? '10.0.0.0/16' : context[:services_ipv4_cidr] %>
|
266
|
+
YAML
|
267
|
+
HubClustersCreator::Utils::Template::Render.new(config).render(template)
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
# rubocop:enable Metrics/ClassLength,Metrics/LineLength,Metrics/MethodLength
|