knife-azure 3.0.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
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