lib/kontena/machine/azure/master_provisioner.rb in kontena-plugin-azure-0.2.5 vs lib/kontena/machine/azure/master_provisioner.rb in kontena-plugin-azure-0.3.0

- old
+ new

@@ -1,111 +1,123 @@ require 'fileutils' require 'erb' require 'open3' require 'json' +require_relative 'common' module Kontena module Machine module Azure class MasterProvisioner include Kontena::Machine::RandomName + include Kontena::Machine::CertHelper include Kontena::Cli::ShellSpinner + include Common attr_reader :client, :http_client # @param [String] subscription_id Azure subscription id # @param [String] certificate Path to Azure management certificate def initialize(subscription_id, certificate) abort('Invalid management certificate') unless File.exists?(File.expand_path(certificate)) @client = ::Azure - client.management_certificate = certificate + client.management_certificate = File.expand_path(certificate) client.subscription_id = subscription_id client.vm_management.initialize_external_logger(Logger.new) # We don't want all the output end def run!(opts) abort('Invalid ssh key') unless File.exists?(File.expand_path(opts[:ssh_key])) + ssl_cert = nil if opts[:ssl_cert] - abort('Invalid ssl cert') unless File.exists?(File.expand_path(opts[:ssl_cert])) + abort('Invalid ssl cert (file not found)') unless File.exists?(File.expand_path(opts[:ssl_cert])) ssl_cert = File.read(File.expand_path(opts[:ssl_cert])) + else + spinner "Generating a self-signed SSL certificate" do + ssl_cert = generate_self_signed_cert + end end + + coreos_image = nil + spinner "Finding latest #{'CoreOS stable'.colorize(:cyan)} image" do + coreos_image = find_coreos_image + end + abort('Cannot find CoreOS image') if coreos_image.nil? + cloud_service_name = generate_cloud_service_name vm_name = cloud_service_name master_url = '' public_ip = nil - spinner "Creating an Azure Virtual Machine #{vm_name.colorize(:cyan)}" do - if opts[:virtual_network].nil? - location = opts[:location].downcase.gsub(' ', '-') - default_network_name = "kontena-#{location}" + if opts[:virtual_network].nil? + location = opts[:location].downcase.gsub(' ', '-') + default_network_name = "kontena-#{location}" + spinner "Creating a virtual network #{default_network_name.colorize(:cyan)}" do create_virtual_network(default_network_name, opts[:location]) unless virtual_network_exist?(default_network_name) - opts[:virtual_network] = default_network_name - opts[:subnet] = 'subnet-1' end + opts[:virtual_network] = default_network_name + opts[:subnet] = 'subnet-1' + end + spinner "Creating an Azure Virtual Machine #{vm_name.colorize(:cyan)} to #{opts[:location].colorize(:cyan)}" do + userdata_vars = opts.merge( ssl_cert: ssl_cert, server_name: opts[:name] || cloud_service_name.sub('kontena-master-', '') ) params = { vm_name: vm_name, vm_user: 'core', location: opts[:location], - image: '2b171e93f07c4903bcad35bda10acf22__CoreOS-Stable-1010.5.0', + image: coreos_image, custom_data: Base64.encode64(user_data(userdata_vars)), ssh_key: opts[:ssh_key] } options = { cloud_service_name: cloud_service_name, deployment_name: vm_name, virtual_network_name: opts[:virtual_network], subnet_name: opts[:subnet], - tcp_endpoints: '80,443', + tcp_endpoints: '443', private_key_file: File.expand_path(opts[:ssh_key]), ssh_port: 22, vm_size: opts[:size], } - virtual_machine = client.vm_management.create_virtual_machine(params,options) public_ip = virtual_machine.ipaddress - - if opts[:ssl_cert] - master_url = "https://#{virtual_machine.ipaddress}" - else - master_url = "http://#{virtual_machine.ipaddress}" - end - + master_url = "https://#{virtual_machine.ipaddress}" end Excon.defaults[:ssl_verify_peer] = false @http_client = Excon.new("#{master_url}", :connect_timeout => 10) - spinner "Waiting for #{vm_name.colorize(:cyan)} to start" do + spinner "Waiting for #{vm_name.colorize(:cyan)} to start (#{master_url})" do sleep 0.5 until master_running? end master_version = nil spinner "Retrieving Kontena Master version" do master_version = JSON.parse(@http_client.get(path: '/').body["version"]) rescue nil end spinner "Kontena Master #{master_version} is now running at #{master_url}".colorize(:green) - { + data = { name: opts[:name] || cloud_service_name.sub('kontena-master-', ''), public_ip: public_ip, provider: 'azure', version: master_version, code: opts[:initial_admin_code] } - end + if respond_to?(:certificate_public_key) && !opts[:ssl_cert] + data[:ssl_certificate] = certificate_public_key(ssl_cert) + end - def erb(template, vars) - ERB.new(template).result(OpenStruct.new(vars).instance_eval { binding }) + data end def user_data(vars) cloudinit_template = File.join(__dir__ , '/cloudinit_master.yml') erb(File.read(cloudinit_template), vars) @@ -117,23 +129,9 @@ false end def generate_cloud_service_name "kontena-master-#{generate_name}-#{rand(1..99)}" - end - - def cloud_service(name) - client.cloud_service_management.get_cloud_service(name) - end - - def virtual_network_exist?(name) - client.network_management.list_virtual_networks.find{|n| n.name == name} - end - - def create_virtual_network(name, location) - address_space = ['10.0.0.0/20'] - options = {subnet: [{:name => 'subnet-1', :ip_address=>'10.0.0.0', :cidr=>23}]} - client.network_management.set_network_configuration(name, location, address_space, options) end end end end end