class HubClustersCreator::Providers::AKS
Public Class Methods
new(provider)
click to toggle source
rubocop:disable Metrics/AbcSize
# File lib/hub-clusters-creator/providers/aks/azure.rb, line 42 def initialize(provider) %i[client_id client_secret region subscription tenant].each do |x| raise ArgumentError, "you must specify the '#{x}' provider option" unless provider.key?(x) end @subscription = provider[:subscription] @tenant = provider[:tenant] @client_id = provider[:client_id] @client_secret = provider[:client_secret] @region = provider[:region] @provider = MsRestAzure::ApplicationTokenProvider.new(@tenant, @client_id, @client_secret) @credentials = MsRest::TokenCredentials.new(@provider) @containers = ::Azure::ContainerService::Mgmt::V2019_04_01::ContainerServiceClient.new(@credentials) @containers.subscription_id = @subscription @dns = ::Azure::Dns::Mgmt::V2017_10_01::DnsManagementClient.new(@credentials) @dns.subscription_id = @subscription options = { client_id: @client_id, client_secret: @client_secret, credentials: @credentials, subscription_id: @subscription, tenant_id: @tenant } @client = Client.new(options) end
Public Instance Methods
create(name, config)
click to toggle source
create is responsible for creating the cluster
# File lib/hub-clusters-creator/providers/aks/azure.rb, line 75 def create(name, config) # @step: validate the user defined options validate(config) # @step: create the infrastructure deployment begin provision_aks(name, config) rescue StandardError => e raise InfrastructureError, "failed to provision cluster, error: #{e}" end # @step: bootstrap the cluster begin provision_cluster(name, config) rescue StandardError => e raise InfrastructureError, "failed to bootstrap cluster, error: #{e}" end end
delete(name)
click to toggle source
delete is responsible for deleting the cluster via resource group
# File lib/hub-clusters-creator/providers/aks/azure.rb, line 95 def delete(name) return unless resource_group?(name) info "deleting the resource group: #{name}" @client.resource_groups.delete(name, name) end
Private Instance Methods
cluster_template(config)
click to toggle source
cluster_template
is responsible for rendering the template for ARM
# File lib/hub-clusters-creator/providers/aks/azure.rb, line 217 def cluster_template(config) template = <<~YAML '$schema': https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json# contentVersion: 1.0.0.0 parameters: {} variables: {} resources: - type: Microsoft.ContainerService/managedClusters name: <%= context[:name] %> apiVersion: '2019-06-01' location: #{@region} tags: cluster: <%= context[:name] %> properties: kubernetesVersion: <%= context[:version] %> dnsPrefix: <%= context[:name] %> addonProfiles: httpapplicationrouting: enabled: true config: HTTPApplicationRoutingZoneName: <%= context[:domain] %> agentPoolProfiles: - name: compute count: <%= context[:size] %> maxPods: 110 osDiskSizeGB: <%= context[:disk_size_gb] %> osType: Linux storageProfile: ManagedDisks type: VirtualMachineScaleSets vmSize: <%= context[:machine_type] %> servicePrincipalProfile: clientId: #{@client_id} secret: #{@client_secret} linuxProfile: adminUsername: azureuser <%- unless (context[:ssh_key] || '').empty? -%> ssh: publicKeys: - keyData: <%= context[:ssh_key] %> <%- end -%> enableRBAC: true enablePodSecurityPolicy: true networkProfile: dnsServiceIP: 10.0.0.10 dockerBridgeCidr: 172.17.0.1/16 loadBalancerSku: basic networkPlugin: azure networkPolicy: azure serviceCidr: <%= context[:services_ipv4_cidr].empty? ? '10.0.0.0/16' : context[:services_ipv4_cidr] %> YAML HubClustersCreator::Utils::Template::Render.new(config).render(template) end
provision_aks(name, config)
click to toggle source
provision_aks
is responsible for provision the infrastructure rubocop:disable Metrics/AbcSize
# File lib/hub-clusters-creator/providers/aks/azure.rb, line 106 def provision_aks(name, config) # @step: define the resource group resource_group_name = name # @step: check the resource group exists if resource_group?(resource_group_name) info "skipping the resource group creation: #{resource_group_name}, already exists" else info "creating the resource group: #{resource_group_name} in azure" params = ::Azure::Resources::Mgmt::V2019_05_10::Models::ResourceGroup.new.tap do |x| x.location = @region end # ensure the resource group is created @client.resource_groups.create_or_update(resource_group_name, params) # wait for the resource group to be created wait(max_retries: 20, interval: 10) do resource_group?(resource_group_name) end end info "provisioning the azure deployment manifest: '#{name}', resource group: '#{resource_group_name}'" # @step: generate the ARM deployments template = YAML.safe_load(cluster_template(config)) # @step: check if a deployment is already underway and wait for completion - which # makes it eaisier to rerun quickly if deployment?(resource_group_name, name) info "deployment: #{name}, resource group: #{resource_group_name} already underway, waiting for completion" wait(interval: 30, max_retries: 20) do if deployment?(resource_group_name, name) d = deployment(resource_group_name, name) d.properties.provisioning_state == 'Succeeded' end end end # @step: kick off the deployment and cross fingers deployment = ::Azure::Resources::Mgmt::V2019_05_10::Models::Deployment.new deployment.properties = ::Azure::Resources::Mgmt::V2019_05_10::Models::DeploymentProperties.new deployment.properties.template = template deployment.properties.mode = ::Azure::Resources::Mgmt::V2019_05_10::Models::DeploymentMode::Incremental # put the deployment to the resource group @client.deployments.create_or_update_async(resource_group_name, name, deployment) # wait for the deployment to finish wait(interval: 30, max_retries: 20) do if deployment?(resource_group_name, name) d = deployment(resource_group_name, name) d.properties.provisioning_state == 'Succeeded' end end end
provision_cluster(name, config)
click to toggle source
provision_cluster
is responsible for kicking off the initialization rubocop:disable Metrics/AbcSize
# File lib/hub-clusters-creator/providers/aks/azure.rb, line 163 def provision_cluster(name, config) resource_group_name = name # @step retrieve the kubeconfig - I HATE everything about Azure!! packed = @containers.managed_clusters.list_cluster_admin_credentials(resource_group_name, name) kc = YAML.safe_load(packed.kubeconfigs.first.value.pack('c*')) ca = kc['clusters'].first['cluster']['certificate-authority-data'] endpoint = URI(kc['clusters'].first['cluster']['server']).hostname # @step: provision a kubernetes client for this cluster kube = HubClustersCreator::Kube.new(endpoint, client_certificate: kc['users'].first['user']['client-certificate-data'], client_key: kc['users'].first['user']['client-key-data']) info "waiting for the kubeapi to become available at: #{endpoint}" kube.wait_for_kubeapi # @step: provision the bootstrap info "attempting to bootstrap the cluster: #{name}" HubClustersCreator::Providers::Bootstrap.new(name, kube, config).bootstrap # @step: update the dns record for the ingress unless (config[:grafana_hostname] || '').empty? # Get the ingress resource and extract the load balancer ip address ingress = @client.get('loki-grafana', 'loki', 'ingresses', version: 'extensions/v1beta1') unless ingress.status.loadBalancer.ingress.empty? address = ingress.status.loadBalancer.ingress.first.ip info "adding a dns record for #{config[:grafana_hostname]} => #{address}" dns(hostname(config[:grafana_hostname]), address, config[:domain]) end end { cluster: { ca: ca, endpoint: "https://#{endpoint}", token: kube.account('sysadmin') }, config: config, services: { grafana: { hostname: config[:grafana_hostname] } } } end
validate(options)
click to toggle source
validate is responsible for validating the options
# File lib/hub-clusters-creator/providers/aks/azure.rb, line 214 def validate(options); end