knife-azure 3.0.0 → 4.0.0

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.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/lib/azure/custom_errors.rb +1 -1
  3. data/lib/azure/resource_management/ARM_deployment_template.rb +5 -5
  4. data/lib/azure/resource_management/ARM_interface.rb +8 -12
  5. data/lib/azure/resource_management/windows_credentials.rb +7 -8
  6. data/lib/chef/knife/azurerm_server_create.rb +2 -2
  7. data/lib/chef/knife/azurerm_server_delete.rb +1 -1
  8. data/lib/chef/knife/bootstrap/bootstrapper.rb +10 -11
  9. data/lib/chef/knife/bootstrap_azurerm.rb +1 -1
  10. data/lib/chef/knife/helpers/azurerm_base.rb +17 -19
  11. data/lib/knife-azure/version.rb +1 -1
  12. metadata +30 -43
  13. data/lib/azure/service_management/ASM_interface.rb +0 -310
  14. data/lib/azure/service_management/ag.rb +0 -99
  15. data/lib/azure/service_management/certificate.rb +0 -235
  16. data/lib/azure/service_management/connection.rb +0 -102
  17. data/lib/azure/service_management/deploy.rb +0 -221
  18. data/lib/azure/service_management/disk.rb +0 -68
  19. data/lib/azure/service_management/host.rb +0 -184
  20. data/lib/azure/service_management/image.rb +0 -94
  21. data/lib/azure/service_management/loadbalancer.rb +0 -78
  22. data/lib/azure/service_management/rest.rb +0 -125
  23. data/lib/azure/service_management/role.rb +0 -717
  24. data/lib/azure/service_management/storageaccount.rb +0 -127
  25. data/lib/azure/service_management/utility.rb +0 -40
  26. data/lib/azure/service_management/vnet.rb +0 -134
  27. data/lib/chef/knife/azure_ag_create.rb +0 -73
  28. data/lib/chef/knife/azure_ag_list.rb +0 -35
  29. data/lib/chef/knife/azure_image_list.rb +0 -56
  30. data/lib/chef/knife/azure_internal-lb_create.rb +0 -74
  31. data/lib/chef/knife/azure_internal-lb_list.rb +0 -35
  32. data/lib/chef/knife/azure_server_create.rb +0 -531
  33. data/lib/chef/knife/azure_server_delete.rb +0 -136
  34. data/lib/chef/knife/azure_server_list.rb +0 -38
  35. data/lib/chef/knife/azure_server_show.rb +0 -41
  36. data/lib/chef/knife/azure_vnet_create.rb +0 -74
  37. data/lib/chef/knife/azure_vnet_list.rb +0 -35
  38. data/lib/chef/knife/bootstrap_azure.rb +0 -191
  39. data/lib/chef/knife/helpers/azure_base.rb +0 -394
@@ -1,102 +0,0 @@
1
- #
2
- # Author:: Barry Davis (barryd@jetstreamsoftware.com)
3
- # Copyright:: Copyright (c) Chef Software Inc.
4
- # License:: Apache License, Version 2.0
5
- #
6
- # Licensed under the Apache License, Version 2.0 (the "License");
7
- # you may not use this file except in compliance with the License.
8
- # You may obtain a copy of the License at
9
- #
10
- # http://www.apache.org/licenses/LICENSE-2.0
11
- #
12
- # Unless required by applicable law or agreed to in writing, software
13
- # distributed under the License is distributed on an "AS IS" BASIS,
14
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
- # See the License for the specific language governing permissions and
16
- # limitations under the License.
17
- #
18
-
19
- require_relative "image"
20
- require_relative "role"
21
- require_relative "deploy"
22
- require_relative "host"
23
- require_relative "loadbalancer"
24
- require_relative "vnet"
25
- require_relative "utility"
26
- require_relative "ag"
27
- require_relative "storageaccount"
28
- require_relative "certificate"
29
- require_relative "disk"
30
-
31
- module Azure
32
- class ServiceManagement
33
- class Connection
34
- include AzureUtility
35
- attr_accessor :hosts, :rest, :images, :deploys, :roles,
36
- :disks, :storageaccounts, :certificates, :ags, :vnets, :lbs
37
- def initialize(rest)
38
- @images = Images.new(self)
39
- @roles = Roles.new(self)
40
- @deploys = Deploys.new(self)
41
- @hosts = Hosts.new(self)
42
- @rest = rest
43
- @lbs = Loadbalancer.new(self)
44
- @vnets = Vnets.new(self)
45
- @ags = AGs.new(self)
46
- @storageaccounts = StorageAccounts.new(self)
47
- @certificates = Certificates.new(self)
48
- @disks = Disks.new(self)
49
- end
50
-
51
- def query_azure(service_name,
52
- verb = "get",
53
- body = "",
54
- params = "",
55
- wait = true,
56
- services = true,
57
- content_type = nil)
58
- Chef::Log.info "calling " + verb + " " + service_name + (wait ? " synchronously" : " asynchronously")
59
- Chef::Log.debug body unless body == ""
60
- response = @rest.query_azure(service_name, verb, body, params, services, content_type)
61
- if response.code.to_i == 200
62
- ret_val = Nokogiri::XML response.body
63
- elsif !wait && response.code.to_i == 202
64
- Chef::Log.debug "Request accepted in asynchronous mode"
65
- ret_val = Nokogiri::XML response.body
66
- elsif response.code.to_i >= 201 && response.code.to_i <= 299
67
- ret_val = wait_for_completion
68
- else
69
- if response.body
70
- ret_val = Nokogiri::XML response.body
71
- Chef::Log.debug ret_val.to_xml
72
- error_code, error_message = error_from_response_xml(ret_val)
73
- Chef::Log.debug error_code + " : " + error_message if error_code.length > 0
74
- else
75
- Chef::Log.warn "http error: " + response.code
76
- end
77
- end
78
- ret_val
79
- end
80
-
81
- def wait_for_completion
82
- status = "InProgress"
83
- Chef::Log.info "Waiting while status returns InProgress"
84
- while status == "InProgress"
85
- response = @rest.query_for_completion
86
- ret_val = Nokogiri::XML response.body
87
- status = xml_content(ret_val, "Status")
88
- if status == "InProgress"
89
- print "."
90
- sleep(0.5)
91
- elsif status == "Succeeded"
92
- Chef::Log.debug "not InProgress : " + ret_val.to_xml
93
- else
94
- error_code, error_message = error_from_response_xml(ret_val)
95
- Chef::Log.debug status + error_code + " : " + error_message if error_code.length > 0
96
- end
97
- end
98
- ret_val
99
- end
100
- end
101
- end
102
- end
@@ -1,221 +0,0 @@
1
- #
2
- # Author:: Barry Davis (barryd@jetstreamsoftware.com)
3
- # Copyright:: Copyright (c) Chef Software Inc.
4
- # License:: Apache License, Version 2.0
5
- #
6
- # Licensed under the Apache License, Version 2.0 (the "License");
7
- # you may not use this file except in compliance with the License.
8
- # You may obtain a copy of the License at
9
- #
10
- # http://www.apache.org/licenses/LICENSE-2.0
11
- #
12
- # Unless required by applicable law or agreed to in writing, software
13
- # distributed under the License is distributed on an "AS IS" BASIS,
14
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
- # See the License for the specific language governing permissions and
16
- # limitations under the License.
17
- #
18
-
19
- module Azure
20
- class Deploys
21
- include AzureUtility
22
- def initialize(connection)
23
- @connection = connection
24
- end
25
-
26
- # force_load should be true when there is something in local cache and we want to reload
27
- # first call is always load.
28
- def load(force_load = false)
29
- unless @deploys || force_load
30
- @deploys = begin
31
- deploys = []
32
- hosts = @connection.hosts.all
33
- hosts.each do |host|
34
- deploy = Deploy.new(@connection)
35
- deploy.retrieve(host.name)
36
- if deploy.name
37
- host.add_deploy(deploy)
38
- deploys << deploy
39
- end
40
- end
41
- deploys
42
- end
43
- end
44
- @deploys
45
- end
46
-
47
- def all
48
- load
49
- end
50
-
51
- # TODO - Current knife-azure plug-in seems to have assumption that single hostedservice
52
- # will always have one deployment (production). see Deploy#retrieve below
53
- def get_deploy_name_for_hostedservice(hostedservicename)
54
- host = @connection.hosts.find(hostedservicename)
55
- if host && host.deploys.length > 0
56
- host.deploys[0].name
57
- else
58
- nil
59
- end
60
- end
61
-
62
- def create(params)
63
- if params[:azure_connect_to_existing_dns]
64
- unless @connection.hosts.exists?(params[:azure_dns_name])
65
- Chef::Log.fatal "The specified Azure DNS Name does not exist."
66
- exit 1
67
- end
68
- else
69
- ret_val = @connection.hosts.create(params)
70
- error_code, error_message = error_from_response_xml(ret_val)
71
- if error_code.length > 0
72
- Chef::Log.fatal "Unable to create DNS:" + error_code + " : " + error_message
73
- exit 1
74
- end
75
- end
76
- unless @connection.storageaccounts.exists?(params[:azure_storage_account])
77
- @connection.storageaccounts.create(params)
78
- end
79
- if params[:ssh_identity_file]
80
- params[:fingerprint] = @connection.certificates.create(params)
81
- end
82
- if params[:cert_path]
83
- cert_data = File.read (params[:cert_path])
84
- @connection.certificates.add cert_data, params[:cert_password], "pfx", params[:azure_dns_name]
85
- elsif params[:winrm_ssl]
86
- # TODO: generate certificates for ssl listener
87
- end
88
-
89
- params["deploy_name"] = get_deploy_name_for_hostedservice(params[:azure_dns_name])
90
-
91
- if !params["deploy_name"].nil?
92
- role = Role.new(@connection)
93
- roleXML = role.setup(params)
94
- ret_val = role.create(params, roleXML)
95
- else
96
- params["deploy_name"] = params[:azure_dns_name]
97
- deploy = Deploy.new(@connection)
98
- deployXML = deploy.setup(params)
99
- ret_val = deploy.create(params, deployXML)
100
- end
101
- error_code, error_message = error_from_response_xml(ret_val)
102
- if error_code.length > 0
103
- Chef::Log.debug(ret_val.to_s)
104
- raise Chef::Log.fatal "Unable to create role:" + error_code + " : " + error_message
105
- end
106
- @connection.roles.find_in_hosted_service(params[:azure_vm_name], params[:azure_dns_name])
107
- end
108
-
109
- def delete(rolename); end
110
-
111
- def queryDeploy(hostedservicename)
112
- deploy = Deploy.new(@connection)
113
- deploy.retrieve(hostedservicename)
114
- deploy
115
- end
116
- end
117
-
118
- class Deploy
119
- include AzureUtility
120
- attr_accessor :connection, :name, :status, :url, :hostedservicename, :input_endpoints, :loadbalancers
121
-
122
- def initialize(connection)
123
- @connection = connection
124
- end
125
-
126
- def retrieve(hostedservicename)
127
- @hostedservicename = hostedservicename
128
- deployXML = @connection.query_azure("hostedservices/#{hostedservicename}/deploymentslots/Production")
129
- if deployXML.at_css("Deployment Name") != nil
130
- @name = xml_content(deployXML, "Deployment Name")
131
- @status = xml_content(deployXML, "Deployment Status")
132
- @url = xml_content(deployXML, "Deployment Url")
133
- @roles = {}
134
- rolesXML = deployXML.css("Deployment RoleInstanceList RoleInstance")
135
- rolesListXML = deployXML.css("Deployment RoleList Role")
136
- rolesXML.zip(rolesListXML).each do |roleXML, roleListXML|
137
- role = Role.new(@connection)
138
- role.parse(roleXML, hostedservicename, @name)
139
- if role.publicipaddress.to_s.empty?
140
- role.publicipaddress = xml_content(deployXML, "VirtualIPs VirtualIP Address")
141
- end
142
- role.parse_role_list_xml(roleListXML)
143
- @roles[role.name] = role
144
- end
145
- @input_endpoints = []
146
- endpointsXML = deployXML.css("InputEndpoint")
147
- endpointsXML.each do |endpointXML|
148
- @input_endpoints << parse_endpoint(endpointXML)
149
- end
150
- @loadbalancers = {}
151
- lbsXML = deployXML.css("Deployment LoadBalancers LoadBalancer")
152
- lbsXML.each do |lbXML|
153
- loadbalancer = Loadbalancer.new(@connection)
154
- loadbalancer.parse(lbXML, hostedservicename)
155
- @loadbalancers[loadbalancer.name] = loadbalancer
156
- end
157
- end
158
- end
159
-
160
- def setup(params)
161
- role = Role.new(@connection)
162
- roleXML = role.setup(params)
163
- builder = Nokogiri::XML::Builder.new do |xml|
164
- xml.Deployment(
165
- "xmlns" => "http://schemas.microsoft.com/windowsazure",
166
- "xmlns:i" => "http://www.w3.org/2001/XMLSchema-instance"
167
- ) do
168
- xml.Name params["deploy_name"]
169
- xml.DeploymentSlot "Production"
170
- xml.Label Base64.encode64(params["deploy_name"]).strip
171
- xml.RoleList { xml.Role("i:type" => "PersistentVMRole") }
172
- if params[:azure_network_name]
173
- xml.VirtualNetworkName params[:azure_network_name]
174
- end
175
- end
176
- end
177
- builder.doc.at_css("Role") << roleXML.at_css("PersistentVMRole").children.to_s
178
- builder.doc
179
- end
180
-
181
- def create(params, deployXML)
182
- servicecall = "hostedservices/#{params[:azure_dns_name]}/deployments"
183
- @connection.query_azure(servicecall, "post", deployXML.to_xml)
184
- end
185
-
186
- # This parses endpoints from a RoleList-Role-InputEndpoint, NOT a RoleInstanceList-RoleInstance-InstanceEndpoint
187
- # Refactor: make this an object rather than a hash..?
188
- def parse_endpoint(inputendpoint_xml)
189
- hash = {}
190
- %w{LoadBalancedEndpointSetName LocalPort Name Port Protocol EnableDirectServerReturn LoadBalancerName IdleTimeoutInMinutes}.each do |key|
191
- hash[key] = xml_content(inputendpoint_xml, key, nil)
192
- end
193
- # Protocol could be in there twice... If we have two, pick the second one as the first is for the probe.
194
- if inputendpoint_xml.css("Protocol").count > 1
195
- hash["Protocol"] = inputendpoint_xml.css("Protocol")[1].content
196
- end
197
- probe = inputendpoint_xml.css("LoadBalancerProbe")
198
- if probe
199
- hash["LoadBalancerProbe"] = {}
200
- %w{Path Port Protocol IntervalInSeconds TimeoutInSeconds}.each do |key|
201
- hash["LoadBalancerProbe"][key] = xml_content(probe, key, nil)
202
- end
203
- end
204
- hash
205
- end
206
-
207
- def roles
208
- @roles.values if @roles
209
- end
210
-
211
- # just delete from local cache
212
- def delete_role_if_present(role)
213
- @roles.delete(role.name) if @roles
214
- end
215
-
216
- def find_role(name)
217
- @roles[name] if @roles
218
- end
219
-
220
- end
221
- end
@@ -1,68 +0,0 @@
1
- #
2
- # Author:: Barry Davis (barryd@jetstreamsoftware.com)
3
- # Copyright:: Copyright (c) Chef Software Inc.
4
- # License:: Apache License, Version 2.0
5
- #
6
- # Licensed under the Apache License, Version 2.0 (the "License");
7
- # you may not use this file except in compliance with the License.
8
- # You may obtain a copy of the License at
9
- #
10
- # http://www.apache.org/licenses/LICENSE-2.0
11
- #
12
- # Unless required by applicable law or agreed to in writing, software
13
- # distributed under the License is distributed on an "AS IS" BASIS,
14
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
- # See the License for the specific language governing permissions and
16
- # limitations under the License.
17
- #
18
-
19
- module Azure
20
- class Disks
21
- def initialize(connection)
22
- @connection = connection
23
- end
24
-
25
- def all
26
- disks = []
27
- response = @connection.query_azure("disks")
28
- founddisks = response.css("Disk")
29
- founddisks.each do |disk|
30
- item = Disk.new(disk)
31
- disks << item
32
- end
33
- disks
34
- end
35
-
36
- def find(name)
37
- founddisk = nil
38
- all.each do |disk|
39
- next unless disk.name == name
40
-
41
- founddisk = disk
42
- end
43
- founddisk
44
- end
45
-
46
- def exists(name)
47
- !find(name).nil?
48
- end
49
-
50
- def clear_unattached
51
- all.each do |disk|
52
- next unless disk.attached == false
53
-
54
- @connection.query_azure("disks/" + disk.name, "delete")
55
- end
56
- end
57
- end
58
- end
59
-
60
- module Azure
61
- class Disk
62
- attr_accessor :name, :attached
63
- def initialize(disk)
64
- @name = disk.at_css("Name").content
65
- @attached = !disk.at_css("AttachedTo").nil?
66
- end
67
- end
68
- end
@@ -1,184 +0,0 @@
1
- #
2
- # Author:: Barry Davis (barryd@jetstreamsoftware.com)
3
- # Copyright:: Copyright (c) Chef Software Inc.
4
- # License:: Apache License, Version 2.0
5
- #
6
- # Licensed under the Apache License, Version 2.0 (the "License");
7
- # you may not use this file except in compliance with the License.
8
- # You may obtain a copy of the License at
9
- #
10
- # http://www.apache.org/licenses/LICENSE-2.0
11
- #
12
- # Unless required by applicable law or agreed to in writing, software
13
- # distributed under the License is distributed on an "AS IS" BASIS,
14
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
- # See the License for the specific language governing permissions and
16
- # limitations under the License.
17
- #
18
-
19
- module Azure
20
- class Hosts
21
- include AzureUtility
22
- def initialize(connection)
23
- @connection = connection
24
- end
25
-
26
- # force_load should be true when there is something in local cache and we want to reload
27
- # first call is always load.
28
- def load(force_load = false)
29
- unless @hosted_services || force_load
30
- @hosted_services = begin
31
- hosted_services = {}
32
- responseXML = @connection.query_azure("hostedservices")
33
- servicesXML = responseXML.css("HostedServices HostedService")
34
- servicesXML.each do |serviceXML|
35
- host = Host.new(@connection).parse(serviceXML)
36
- hosted_services[host.name] = host
37
- end
38
- hosted_services
39
- end
40
- end
41
- @hosted_services
42
- end
43
-
44
- def all
45
- load.values
46
- end
47
-
48
- # first look up local cache if we have already loaded list.
49
- def exists?(name)
50
- return @hosted_services.key?(name) if @hosted_services
51
-
52
- exists_on_cloud?(name)
53
- end
54
-
55
- # Look up on cloud and not local cache
56
- def exists_on_cloud?(name)
57
- ret_val = @connection.query_azure("hostedservices/#{name}")
58
- error_code, error_message = error_from_response_xml(ret_val) if ret_val
59
- if ret_val.nil? || error_code.length > 0
60
- Chef::Log.debug("Unable to find hosted(cloud) service:" + error_code + " : " + error_message) if ret_val
61
- false
62
- else
63
- true
64
- end
65
- end
66
-
67
- # first look up local cache if we have already loaded list.
68
- def find(name)
69
- return @hosted_services[name] if @hosted_services && @hosted_services.key?(name)
70
-
71
- fetch_from_cloud(name)
72
- end
73
-
74
- # Look up hosted service on cloud and not local cache
75
- def fetch_from_cloud(name)
76
- ret_val = @connection.query_azure("hostedservices/#{name}")
77
- error_code, error_message = error_from_response_xml(ret_val) if ret_val
78
- if ret_val.nil? || error_code.length > 0
79
- Chef::Log.warn("Unable to find hosted(cloud) service:" + error_code + " : " + error_message) if ret_val
80
- nil
81
- else
82
- Host.new(@connection).parse(ret_val)
83
- end
84
- end
85
-
86
- def create(params)
87
- host = Host.new(@connection)
88
- host.create(params)
89
- end
90
-
91
- def delete(name)
92
- if exists?(name)
93
- servicecall = "hostedservices/" + name
94
- @connection.query_azure(servicecall, "delete")
95
- end
96
- end
97
- end
98
- end
99
-
100
- module Azure
101
- class Host
102
- include AzureUtility
103
- attr_accessor :connection, :name, :url, :label
104
- attr_accessor :dateCreated, :description, :location
105
- attr_accessor :dateModified, :status
106
-
107
- def initialize(connection)
108
- @connection = connection
109
- @deploys_loaded = false
110
- @deploys = {}
111
- end
112
-
113
- def parse(serviceXML)
114
- @name = xml_content(serviceXML, "ServiceName")
115
- @url = xml_content(serviceXML, "Url")
116
- @label = xml_content(serviceXML, "HostedServiceProperties Label")
117
- @dateCreated = xml_content(serviceXML, "HostedServiceProperties DateCreated")
118
- @description = xml_content(serviceXML, "HostedServiceProperties Description")
119
- @location = xml_content(serviceXML, "HostedServiceProperties Location")
120
- @dateModified = xml_content(serviceXML, "HostedServiceProperties DateLastModified")
121
- @status = xml_content(serviceXML, "HostedServiceProperties Status")
122
- self
123
- end
124
-
125
- def create(params)
126
- builder = Nokogiri::XML::Builder.new do |xml|
127
- xml.CreateHostedService("xmlns" => "http://schemas.microsoft.com/windowsazure") do
128
- xml.ServiceName params[:azure_dns_name]
129
- xml.Label Base64.encode64(params[:azure_dns_name])
130
- xml.Description "Explicitly created hosted service"
131
- unless params[:azure_service_location].nil?
132
- xml.Location params[:azure_service_location]
133
- end
134
- unless params[:azure_affinity_group].nil?
135
- xml.AffinityGroup params[:azure_affinity_group]
136
- end
137
- end
138
- end
139
- @connection.query_azure("hostedservices", "post", builder.to_xml)
140
- end
141
-
142
- def details
143
- response = @connection.query_azure("hostedservices/" + @name + "?embed-detail=true")
144
- end
145
-
146
- # Deployments within this hostedservice
147
- def add_deploy(deploy)
148
- @deploys[deploy.name] = deploy
149
- end
150
-
151
- def delete_role(role)
152
- deploys.each { |d| d.delete_role_if_present(role) }
153
- end
154
-
155
- def deploys
156
- # check if we have deploys loaded, else load.
157
- if (@deploys.length == 0) && !@deploys_loaded
158
- deploy = Deploy.new(@connection)
159
- deploy.retrieve(@name)
160
- @deploys[deploy.name] = deploy
161
- @deploys_loaded = true
162
- end
163
- @deploys.values
164
- end
165
-
166
- def roles
167
- roles = []
168
- deploys.each do |deploy|
169
- roles.concat(deploy.roles) if deploy.roles
170
- end
171
- roles
172
- end
173
-
174
- def find_role(role_name, deploy_name = nil)
175
- return @deploys[deploy_name].find_role(role_name) if deploy_name && deploys
176
-
177
- # else lookup all deploys within hostedservice
178
- deploys.each do |deploy|
179
- role = deploy.find_role(role_name)
180
- return role if role
181
- end
182
- end
183
- end
184
- end