Class: Chef::Knife::BootstrapAzure

Inherits:
Bootstrap
  • Object
show all
Includes:
AzureBase, Chef::Knife::Bootstrap::Bootstrapper, Chef::Knife::Bootstrap::CommonBootstrapOptions
Defined in:
lib/chef/knife/bootstrap_azure.rb

Instance Method Summary collapse

Methods included from Chef::Knife::Bootstrap::Bootstrapper

#create_node_and_client_pem, #default_hint_options, #get_chef_extension_name, #get_chef_extension_private_params, #get_chef_extension_public_params, #get_chef_extension_publisher, #get_chef_extension_version, #load_correct_secret, #ohai_hints

Methods included from Chef::Knife::Bootstrap::CommonBootstrapOptions

included

Methods included from AzureBase

#fetch_chef_client_logs, #fetch_deployment, #fetch_extension, #fetch_role, #fetch_substatus, #find_file, #get_azure_profile_file_path, #get_default_subscription, included, #is_image_windows?, #msg_pair, #msg_server_summary, #parse_azure_profile, #parse_publish_settings_file, #pretty_key, #service, #validate!, #validate_asm_keys!, #validate_params!

Instance Method Details

#connect!Object

Following methods are not required



75
# File 'lib/chef/knife/bootstrap_azure.rb', line 75

def connect!; end

#perform_bootstrap(bootstrap_path) ⇒ Object



83
# File 'lib/chef/knife/bootstrap_azure.rb', line 83

def perform_bootstrap(bootstrap_path); end

#plugin_create_instance!Object



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/chef/knife/bootstrap_azure.rb', line 52

def plugin_create_instance!
  if @name_args.length == 1
    service.add_extension(@name_args[0], set_ext_params)
    if config[:extended_logs]
      print "\n\nWaiting for the Chef Extension to become available/ready"
      wait_until_extension_available(Time.now, 10)
      print "\n\nWaiting for the first chef-client run"
      fetch_chef_client_logs(Time.now, 35)
    end
  else
    raise ArgumentError, "Please specify the SERVER name which needs to be bootstrapped via the Chef Extension." if @name_args.empty?
    raise ArgumentError, "Please specify only one SERVER name which needs to be bootstrapped via the Chef Extension." if @name_args.length > 1
  end
rescue StandardError => error
  ui.error(error.message.to_s)
  Chef::Log.debug(error.backtrace.join("\n").to_s)
  exit
end

#plugin_finalizeObject



71
# File 'lib/chef/knife/bootstrap_azure.rb', line 71

def plugin_finalize; end

#plugin_setup!Object

run() would be executing from parent class Chef::Knife::Bootstrap, defined in core. Required methods have been overridden here run() execution begins ####



43
# File 'lib/chef/knife/bootstrap_azure.rb', line 43

def plugin_setup!; end

#plugin_validate_options!Object



47
48
49
50
# File 'lib/chef/knife/bootstrap_azure.rb', line 47

def plugin_validate_options!
  ui.info "Validating..."
  validate_asm_keys!
end

#register_clientObject



77
# File 'lib/chef/knife/bootstrap_azure.rb', line 77

def register_client; end

#render_templateObject



79
# File 'lib/chef/knife/bootstrap_azure.rb', line 79

def render_template; end

#set_ext_paramsObject

run() execution ends ####



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/chef/knife/bootstrap_azure.rb', line 87

def set_ext_params
  begin
    ui.info "Looking for the server #{@name_args[0]}..."
    server = service.find_server(
      name: @name_args[0],
      azure_dns_name: config[:azure_dns_name]
    )

    ## if azure_dns_name value not passed by user then set it using the hostedservicename attribute from the retrieved server's object ##
    config[:azure_dns_name] = server.hostedservicename if config[:azure_dns_name].nil? && (server.instance_of? Azure::Role)
    unless server.instance_of? Azure::Role
      if server.nil?
        if !config[:azure_dns_name].nil?
          raise "Hosted service #{config[:azure_dns_name]} does not exist."
        else
          raise "Server #{@name_args[0]} does not exist."
        end
      else
        raise "Server #{@name_args[0]} does not exist under the hosted service #{config[:azure_dns_name]}."
      end
    end

    ui.info "\nServer #{@name_args[0]} found."
    ui.info "Setting the Chef Extension parameters."
    ext_params = {}
    case server.os_type.downcase
    when "windows"
      ext_params[:chef_extension] = "ChefClient"
    when "linux"
      if %w{ubuntu debian rhel centos}.any? { |platform| server.os_version.downcase.include? platform }
        ext_params[:chef_extension] = "LinuxChefClient"
      else
        raise "OS version #{server.os_version} for OS type #{server.os_type} is not supported."
      end
    else
      raise "OS type #{server.os_type} is not supported."
    end

    ext_params[:azure_dns_name] = server.hostedservicename || config[:azure_dns_name]
    ext_params[:deploy_name] = server.deployname
    ext_params[:role_xml] = server.role_xml
    ext_params[:azure_vm_name] = @name_args[0]
    ext_params[:chef_extension_publisher] = get_chef_extension_publisher
    ext_params[:chef_extension_version] = get_chef_extension_version(ext_params[:chef_extension])
    ext_params[:chef_extension_public_param] = get_chef_extension_public_params
    ext_params[:chef_extension_private_param] = get_chef_extension_private_params
  rescue => error
    ui.error("#{error.message}")
    Chef::Log.debug("#{error.backtrace.join("\n")}")
    exit
  end

  ext_params
end

#upload_bootstrap(content) ⇒ Object



81
# File 'lib/chef/knife/bootstrap_azure.rb', line 81

def upload_bootstrap(content); end

#validate_name_args!Object



45
# File 'lib/chef/knife/bootstrap_azure.rb', line 45

def validate_name_args!; end

#wait_until_extension_available(extension_deploy_start_time, extension_availaibility_wait_timeout) ⇒ Object



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/chef/knife/bootstrap_azure.rb', line 142

def wait_until_extension_available(extension_deploy_start_time, extension_availaibility_wait_timeout)
  extension_availaibility_wait_time = ((Time.now - extension_deploy_start_time) / 60).round
  if extension_availaibility_wait_time <= extension_availaibility_wait_timeout
    ## extension availaibility wait time has not exceeded the maximum threshold set for the wait timeout ##
    my_role = nil
    sleep_and_wait = false
    deployment = fetch_deployment
    if deployment.at_css("Deployment Name") != nil
      role_list_xml = deployment.css("RoleInstanceList RoleInstance")
      ## list of roles found under the deployment ##
      role_list_xml.each do |role|
        ## search in the roles list for the given role ##
        if role.at_css("RoleName").text == @name_args[0]
          my_role = role
          break
        end
      end

      if my_role && my_role.at_css("GuestAgentStatus Status").text == "Ready"
        ## given role found and also GuestAgent is ready ##
        extension = fetch_extension(my_role)
        ## check if Chef Extension not found (which means it is not available/ready yet) then sleep_and_wait OR
        ## if found (which means it is available/ready now) then proceed further with chef-client run logs fetch process ##
        sleep_and_wait = true if extension.nil?
      else
        ## given role not found or GuestAgent not ready yet ##
        sleep_and_wait = true
      end
    else
      ## deployment could not be found ##
      sleep_and_wait = true
    end

    ## wait for some time and then re-fetch the status ##
    if sleep_and_wait == true
      print "#{ui.color(".", :bold)}"
      sleep 30
      wait_until_extension_available(
        extension_deploy_start_time,
        extension_availaibility_wait_timeout
      )
    end
  else
    ## extension availaibility wait time exceeded maximum threshold set for the wait timeout ##
    raise "\nUnable to fetch chef-client run logs as Chef Extension seems to be unavailable even after #{extension_availaibility_wait_timeout} minutes of its deployment.\n"
  end
end