chef-provisioning-azurerm 0.2.14 → 0.3.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +31 -24
- data/lib/chef/provider/azure_resource_group.rb +10 -13
- data/lib/chef/provider/azure_resource_template.rb +51 -78
- data/lib/chef/provisioning/azurerm.rb +2 -0
- data/lib/chef/provisioning/azurerm/azure_provider.rb +5 -43
- data/lib/chef/provisioning/azurerm/azure_resource.rb +0 -2
- data/lib/chef/provisioning/azurerm/credentials.rb +11 -31
- data/lib/chef/provisioning/azurerm/version.rb +1 -1
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7d176236bac9897ee22d2e60033bdfbad9d25796
|
4
|
+
data.tar.gz: 68c52c8d7981aea6e7924cf8d03e3adac0a1583b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 29dd37fd7ed0bc40ad827a7df2e60098c74983ea9b6190c658aecc0b88d2959384299e1461377f38b362aa83c2c5e35cd2476ce59d22f1e14777454295b0bd67
|
7
|
+
data.tar.gz: f7f8969fb4d2782f64a31c23d9d06597d686466516241ca7e523b881e5fcb0e66975e54b5c73b9a07747b34196e7248afc4c8d0563e964e6f185d5f864a8e570
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
# chef-provisioning-azurerm Changelog
|
2
2
|
|
3
|
+
## [0.3.0] - 2015-09-04
|
4
|
+
### Changed
|
5
|
+
- Now using ARM functionality from the updated [Azure SDK for Ruby](http://github.com/azure/azure-sdk-for-ruby) rather than direct HTTPS calls to the Resource Manager API.
|
6
|
+
- **BREAKING CHANGE** Authentication to Azure must now be via Service Principal, not username and password as previous. See the [README.md](https://github.com/pendrica/chef-provisioning-azurerm) for more details.
|
7
|
+
|
3
8
|
## [0.2.14] - 2015-08-21
|
4
9
|
### Changed
|
5
10
|
- Minimize logging to info, favour action_handler.report_progress
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# chef-provisioning-azurerm
|
2
2
|
|
3
|
-
```chef-provisioning-azurerm``` is a driver for [chef-provisioning](https://github.com/chef/chef-provisioning) that allows Microsoft Azure resources to be provisioned by Chef. This driver uses the new Microsoft Azure Resource Management REST API.
|
3
|
+
```chef-provisioning-azurerm``` is a driver for [chef-provisioning](https://github.com/chef/chef-provisioning) that allows Microsoft Azure resources to be provisioned by Chef. This driver uses the new Microsoft Azure Resource Management REST API via the [azure-sdk-for-ruby](https://github.com/azure/azure-sdk-for-ruby).
|
4
4
|
|
5
5
|
**current status: prototype/experimental - use at own risk!**
|
6
6
|
|
@@ -24,23 +24,28 @@ This plugin is distributed as a Ruby Gem. To install it, run:
|
|
24
24
|
|
25
25
|
### Configuration
|
26
26
|
|
27
|
-
For the driver to interact with the Microsoft Azure Resource management REST API, a
|
27
|
+
For the driver to interact with the Microsoft Azure Resource management REST API, a Service Principal needs to be configured with Owner rights against the specific subscription being targeted. Using an Organization account and related password is no longer supported. To create a Service Principal and apply the correct permissions, follow the instructions in the article: [Authenticating a service principal with Azure Resource Manager](https://azure.microsoft.com/en-us/documentation/articles/resource-group-authenticate-service-principal/#authenticate-service-principal-with-password---azure-cli)
|
28
28
|
|
29
|
-
|
29
|
+
You will essentially need 4 parameters from the above article to configure Chef Provisioning: **Subscription ID**, **Client ID**, **Client Secret/Password** and **Tenant ID**. These can be easily obtained using the azure-cli tools (v0.9.8 or higher) on any platform.
|
30
30
|
|
31
31
|
Using a text editor, open or create the file ```~/.azure/credentials``` and add the following section:
|
32
32
|
|
33
33
|
```ruby
|
34
34
|
[abcd1234-YOUR-GUID-HERE-abcdef123456]
|
35
|
-
|
36
|
-
|
35
|
+
client_id = "48b9bba3-YOUR-GUID-HERE-90f0b68ce8ba"
|
36
|
+
client_secret = "your-client-secret-here"
|
37
|
+
tenant_id = "9c117323-YOUR-GUID-HERE-9ee430723ba3"
|
37
38
|
```
|
38
39
|
|
39
|
-
|
40
|
+
If preferred, you may also set the following environment variables on the "provisioning node", replacing the values with those obtained when you configured the service principal
|
40
41
|
|
41
|
-
|
42
|
+
```ruby
|
43
|
+
AZURE_CLIENT_ID="48b9bba3-YOUR-GUID-HERE-90f0b68ce8ba"
|
44
|
+
AZURE_CLIENT_SECRET="your-client-secret-here"
|
45
|
+
AZURE_TENANT_ID="9c117323-YOUR-GUID-HERE-9ee430723ba3"
|
46
|
+
```
|
42
47
|
|
43
|
-
|
48
|
+
Note that the environment variables, if set, take preference over the values in a configuration file. The subscription id will be taken from the recipe.
|
44
49
|
|
45
50
|
## Features
|
46
51
|
|
@@ -53,8 +58,8 @@ To work around the issue of storing chef-provisioning driver info in the Chef se
|
|
53
58
|
The following resources are provided:
|
54
59
|
|
55
60
|
- azure_resource_group
|
56
|
-
- azure_storage_account
|
57
61
|
- azure_resource_template
|
62
|
+
- azure_storage_account
|
58
63
|
|
59
64
|
The following resources are planned (note: these resources may be renamed as they are implemented):
|
60
65
|
|
@@ -89,32 +94,34 @@ For our example, we'll need the azure_deploy.json from [here](https://raw.github
|
|
89
94
|
require 'chef/provisioning/azurerm'
|
90
95
|
with_driver 'AzureRM:abcd1234-YOUR-GUID-HERE-abcdef123456'
|
91
96
|
|
92
|
-
azure_resource_group 'pendrica-demo
|
97
|
+
azure_resource_group 'pendrica-demo' do
|
93
98
|
location 'West US' # optional, default: 'West US'
|
94
99
|
tags businessUnit: 'IT' # optional
|
95
100
|
end
|
96
101
|
|
97
102
|
azure_resource_template 'my-deployment' do
|
98
|
-
resource_group 'pendrica-demo
|
103
|
+
resource_group 'pendrica-demo'
|
99
104
|
template_source 'cookbooks/provision/files/default/azure_deploy.json'
|
100
|
-
parameters newStorageAccountName:
|
101
|
-
adminUsername: '
|
105
|
+
parameters newStorageAccountName: "mystorageaccount01",
|
106
|
+
adminUsername: 'stuart',
|
102
107
|
adminPassword: 'P2ssw0rd',
|
103
|
-
dnsNameForPublicIP:
|
104
|
-
|
108
|
+
dnsNameForPublicIP: "my-demo-server",
|
109
|
+
windowsOSVersion: '2012-R2-Datacenter'
|
105
110
|
chef_extension client_type: 'ChefClient',
|
106
|
-
version: '
|
107
|
-
runlist: '
|
111
|
+
version: '1210.12',
|
112
|
+
runlist: 'role[webserver]'
|
108
113
|
end
|
109
114
|
```
|
110
115
|
|
111
|
-
**Note: If no chef_extension configuration is specified, the ARM template will imported without enabling the Azure Chef VM Extension
|
116
|
+
**Note: If no chef_extension configuration is specified, the ARM template will imported without enabling the Azure Chef VM Extension.**
|
112
117
|
|
113
118
|
The Chef Server URL, Validation Client name and Validation Key content are not currently exposed parameters but can be overridden via setting the following Chef::Config parameters (via modifying ```c:\chef\client.rb``` or specifying ```-c path\to\client.rb``` on the ```chef-client``` command line).
|
114
119
|
|
115
|
-
|
116
|
-
|
117
|
-
|
120
|
+
```ruby
|
121
|
+
Chef::Config[:chef_server_url]
|
122
|
+
Chef::Config[:validation_client_name]
|
123
|
+
Chef::Config[:validation_key]
|
124
|
+
```
|
118
125
|
|
119
126
|
## Example Recipe 2 - deployment of locally replicated Storage Account
|
120
127
|
### example2.rb
|
@@ -123,12 +130,12 @@ The Chef Server URL, Validation Client name and Validation Key content are not c
|
|
123
130
|
require 'chef/provisioning/azurerm'
|
124
131
|
with_driver 'AzureRM:abcd1234-YOUR-GUID-HERE-abcdef123456'
|
125
132
|
|
126
|
-
azure_resource_group 'pendrica-demo
|
133
|
+
azure_resource_group 'pendrica-demo' do
|
127
134
|
location 'West US'
|
128
135
|
end
|
129
136
|
|
130
|
-
azure_storage_account '
|
131
|
-
resource_group 'pendrica-demo
|
137
|
+
azure_storage_account 'mystorageaccount02' do
|
138
|
+
resource_group 'pendrica-demo'
|
132
139
|
location 'West US'
|
133
140
|
account_type 'Standard_LRS'
|
134
141
|
end
|
@@ -9,26 +9,23 @@ class Chef
|
|
9
9
|
true
|
10
10
|
end
|
11
11
|
|
12
|
-
def api_url
|
13
|
-
"https://management.azure.com/subscriptions/#{new_resource.subscription_id}/resourcegroups/" \
|
14
|
-
"#{new_resource.name}?api-version=2015-01-01"
|
15
|
-
end
|
16
|
-
|
17
|
-
# API ref: https://msdn.microsoft.com/en-us/library/azure/dn790525.aspx
|
18
12
|
action :create do
|
19
13
|
converge_by("create or update Resource Group #{new_resource.name}") do
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
azure_call_until_expected_response(:put, api_url, doc.to_json, '201,200', 60)
|
14
|
+
resource_group = Azure::ARM::Resources::Models::ResourceGroup.new
|
15
|
+
resource_group.location = new_resource.location
|
16
|
+
resource_group.tags = new_resource.tags
|
17
|
+
result = resource_management_client.resource_groups.create_or_update(new_resource.name, resource_group).value!
|
25
18
|
end
|
26
19
|
end
|
27
20
|
|
28
|
-
# API ref: https://msdn.microsoft.com/en-us/library/azure/dn790539.aspx
|
29
21
|
action :destroy do
|
30
22
|
converge_by("destroy Resource Group #{new_resource.name}") do
|
31
|
-
|
23
|
+
resource_group_exists = resource_management_client.resource_groups.check_existence(new_resource.name).value!
|
24
|
+
if resource_group_exists.body == "true"
|
25
|
+
result = resource_management_client.resource_groups.delete(new_resource.name).value!
|
26
|
+
else
|
27
|
+
action_handler.report_progress "Resource Group #{new_resource.name} was not found."
|
28
|
+
end
|
32
29
|
end
|
33
30
|
end
|
34
31
|
end
|
@@ -9,42 +9,44 @@ class Chef
|
|
9
9
|
true
|
10
10
|
end
|
11
11
|
|
12
|
-
# Applies a Resource Manager template to Azure.
|
13
|
-
# If resources of type Microsoft.Compute/virtualMachines are found, a Chef VM Extension is added
|
14
|
-
# Chef VM Extension parameters may be supplied in the recipe.
|
15
12
|
action :deploy do
|
16
13
|
converge_by("deploy or re-deploy Resource Manager template '#{new_resource.name}'") do
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
14
|
+
result = resource_management_client.deployments.create_or_update(new_resource.resource_group, new_resource.name, deployment).value!
|
15
|
+
action_handler.report_progress "Result: #{result.body.properties.provisioning_state}"
|
16
|
+
Chef::Log.debug("result: #{result.body.inspect}")
|
17
|
+
follow_deployment_until_end_state
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def deployment
|
22
|
+
deployment = Azure::ARM::Resources::Models::Deployment.new
|
23
|
+
deployment.properties = Azure::ARM::Resources::Models::DeploymentProperties.new
|
24
|
+
deployment.properties.template = template
|
25
|
+
deployment.properties.mode = Azure::ARM::Resources::Models::DeploymentMode::Incremental
|
26
|
+
deployment.properties.parameters = parameters_in_values_format
|
27
|
+
deployment
|
28
|
+
end
|
29
|
+
|
30
|
+
def template
|
31
|
+
template_src_file = ::File.join(Chef::Config[:chef_repo_path], new_resource.template_source)
|
32
|
+
fail "Cannot find file: #{template_src_file}" unless ::File.file?(template_src_file)
|
33
|
+
template = JSON.parse(::IO.read(template_src_file))
|
34
|
+
if new_resource.chef_extension
|
35
|
+
machines = template['resources'].select { |h| h['type'] == 'Microsoft.Compute/virtualMachines' }
|
36
|
+
machines.each do |machine|
|
37
|
+
action_handler.report_progress "adding a Chef VM Extension with name: #{machine['name']} and location: #{machine['location']} "
|
38
|
+
extension = chef_vm_extension(machine['name'], machine['location'])
|
39
|
+
template['resources'] << JSON.parse(extension)
|
28
40
|
end
|
29
|
-
Chef::Log.debug("[Azure] Generated template for deployment: #{template}")
|
30
|
-
doc = generate_wrapper_document(template)
|
31
|
-
apply_template_deployment(doc)
|
32
|
-
follow_deployment_until_ended
|
33
41
|
end
|
42
|
+
template
|
34
43
|
end
|
35
44
|
|
36
|
-
def
|
45
|
+
def parameters_in_values_format
|
37
46
|
parameters = new_resource.parameters.map do |key, value|
|
38
47
|
{ key.to_sym => { 'value' => value } }
|
39
48
|
end
|
40
|
-
|
41
|
-
properties: {
|
42
|
-
template: template,
|
43
|
-
mode: 'Incremental',
|
44
|
-
parameters: parameters.reduce(:merge!)
|
45
|
-
}
|
46
|
-
}
|
47
|
-
new_template
|
49
|
+
parameters.reduce(:merge!)
|
48
50
|
end
|
49
51
|
|
50
52
|
def chef_vm_extension(machine_name, location)
|
@@ -80,65 +82,36 @@ class Chef
|
|
80
82
|
EOH
|
81
83
|
end
|
82
84
|
|
83
|
-
def
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
else
|
92
|
-
fail "#{response.body}" if response.body
|
85
|
+
def follow_deployment_until_end_state
|
86
|
+
end_provisioning_states = 'Canceled,Failed,Deleted,Succeeded'
|
87
|
+
end_provisioning_state_reached = false
|
88
|
+
until end_provisioning_state_reached
|
89
|
+
list_outstanding_deployment_operations
|
90
|
+
sleep 5
|
91
|
+
deployment_provisioning_state = deployment_state
|
92
|
+
end_provisioning_state_reached = end_provisioning_states.split(',').include?(deployment_provisioning_state)
|
93
93
|
end
|
94
|
+
action_handler.report_progress "Resource Template deployment reached end state of '#{deployment_provisioning_state}'."
|
94
95
|
end
|
95
96
|
|
96
|
-
def
|
97
|
-
url = "https://management.azure.com/subscriptions/#{new_resource.subscription_id}/resourcegroups/" \
|
98
|
-
"#{new_resource.resource_group}/providers/microsoft.resources/deployments/#{new_resource.name}" \
|
99
|
-
'/validate?api-version=2015-01-01'
|
100
|
-
response = azure_call(:post, url, doc.to_json)
|
101
|
-
Chef::Log.info("[Azure] #{response.body.inspect}")
|
102
|
-
end
|
103
|
-
|
104
|
-
# API ref: https://msdn.microsoft.com/en-us/library/azure/dn790565.aspx (Deployment)
|
105
|
-
# API ref: https://msdn.microsoft.com/en-us/library/azure/dn790519.aspx (Operations)
|
106
|
-
def follow_deployment_until_ended
|
107
|
-
url = "https://management.azure.com/subscriptions/#{new_resource.subscription_id}/resourcegroups/" \
|
108
|
-
"#{new_resource.resource_group}/providers/microsoft.resources/deployments/#{new_resource.name}" \
|
109
|
-
'/operations?api-version=2015-01-01'
|
110
|
-
|
111
|
-
end_provisioning_states = 'Canceled,Failed,Deleted,Succeeded'
|
97
|
+
def list_outstanding_deployment_operations
|
112
98
|
end_operation_states = 'Failed,Succeeded'
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
resource_name = val['properties']['targetResource']['resourceName']
|
122
|
-
resource_type = val['properties']['targetResource']['resourceType']
|
123
|
-
end_operation_state_reached = end_operation_states.split(',').include?(resource_provisioning_state)
|
124
|
-
unless end_operation_state_reached
|
125
|
-
action_handler.report_progress "Resource #{resource_type} '#{resource_name}' provisioning status is #{resource_provisioning_state}\n"
|
126
|
-
end
|
99
|
+
deployment_operations = resource_management_client.deployment_operations.list(new_resource.resource_group, new_resource.name).value!
|
100
|
+
deployment_operations.body.value.each do |val|
|
101
|
+
resource_provisioning_state = val.properties.provisioning_state
|
102
|
+
resource_name = val.properties.target_resource.resource_name
|
103
|
+
resource_type = val.properties.target_resource.resource_type
|
104
|
+
end_operation_state_reached = end_operation_states.split(',').include?(resource_provisioning_state)
|
105
|
+
unless end_operation_state_reached
|
106
|
+
action_handler.report_progress "Resource #{resource_type} '#{resource_name}' provisioning status is #{resource_provisioning_state}\n"
|
127
107
|
end
|
128
|
-
sleep 5
|
129
|
-
provisioning_state = retrieve_provisioning_state
|
130
|
-
Chef::Log.debug("[Azure] Resource Template deployment is in a state of '#{provisioning_state}'")
|
131
|
-
end_provisioning_state_reached = end_provisioning_states.split(',').include?(provisioning_state)
|
132
108
|
end
|
133
|
-
action_handler.report_progress "Resource Template deployment reached end state of '#{provisioning_state}'."
|
134
109
|
end
|
135
110
|
|
136
|
-
def
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
response = azure_call(:get, url, '')
|
141
|
-
JSON.parse(response.body)['properties']['provisioningState']
|
111
|
+
def deployment_state
|
112
|
+
deployments = resource_management_client.deployments.get(new_resource.resource_group, new_resource.name).value!
|
113
|
+
Chef::Log.debug("deployments result: #{deployments.body.inspect}")
|
114
|
+
deployments.body.properties.provisioning_state
|
142
115
|
end
|
143
116
|
end
|
144
117
|
end
|
@@ -2,6 +2,8 @@ require 'chef/provisioning'
|
|
2
2
|
require 'chef/provisioning/version'
|
3
3
|
require 'chef/provisioning/azurerm/driver'
|
4
4
|
require 'chef/provisioning/azurerm/version'
|
5
|
+
require 'azure_mgmt_resources'
|
6
|
+
|
5
7
|
Chef::Log.info("chef-provisioning-azurerm #{Chef::Provisioning::AzureRM::VERSION}")
|
6
8
|
Chef::Log.info("chef-provisioning #{Chef::Provisioning::VERSION}")
|
7
9
|
|
@@ -12,49 +12,11 @@ class Chef
|
|
12
12
|
@action_handler ||= Chef::Provisioning::ChefProviderActionHandler.new(self)
|
13
13
|
end
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
|
21
|
-
case method
|
22
|
-
when :put
|
23
|
-
request = Net::HTTP::Put.new uri
|
24
|
-
when :delete
|
25
|
-
request = Net::HTTP::Delete.new uri
|
26
|
-
when :get
|
27
|
-
request = Net::HTTP::Get.new uri
|
28
|
-
when :post
|
29
|
-
request = Net::HTTP::Post.new uri
|
30
|
-
when :patch
|
31
|
-
request = Net::HTTP::Patch.new uri
|
32
|
-
end
|
33
|
-
request.body = data
|
34
|
-
request['Authorization'] = "Bearer #{new_resource.access_token}"
|
35
|
-
request['Content-Type'] = 'application/json'
|
36
|
-
response = http.request request
|
37
|
-
end
|
38
|
-
response
|
39
|
-
end
|
40
|
-
|
41
|
-
# Wraps a call to the Azure REST API with retry and timeout capability.
|
42
|
-
def azure_call_until_expected_response(method, url, data, success_codes, wait_time)
|
43
|
-
time_elapsed = 0
|
44
|
-
sleep_time = 2
|
45
|
-
max_wait_time = wait_time
|
46
|
-
success_code_found = false
|
47
|
-
while time_elapsed < max_wait_time && !success_code_found
|
48
|
-
response = azure_call(method, url, data)
|
49
|
-
break if response.code.to_i >= 400
|
50
|
-
success_code_found = success_codes.split(',').include?(response.code)
|
51
|
-
break if success_code_found
|
52
|
-
Chef::Log.debug("awaiting success code (#{success_codes}) (got: #{response.code}) - timeout in #{(max_wait_time - time_elapsed)} seconds.")
|
53
|
-
sleep(sleep_time)
|
54
|
-
time_elapsed += sleep_time
|
55
|
-
end
|
56
|
-
Chef::Log.debug("response code: #{response.code} body: #{response.body}")
|
57
|
-
response
|
15
|
+
def resource_management_client
|
16
|
+
credentials = Credentials.new.azure_credentials_for_subscription(new_resource.subscription_id)
|
17
|
+
client = Azure::ARM::Resources::ResourceManagementClient.new(credentials)
|
18
|
+
client.subscription_id = new_resource.subscription_id
|
19
|
+
client
|
58
20
|
end
|
59
21
|
end
|
60
22
|
end
|
@@ -13,12 +13,10 @@ class Chef
|
|
13
13
|
@driver = run_context.chef_provisioning.current_driver
|
14
14
|
fail 'No driver set. (has it been set in your recipe using with_driver?)' unless driver
|
15
15
|
@driver_name, @subscription_id = driver.split(':', 2)
|
16
|
-
@access_token = Credentials.new.access_token_for_subscription(@subscription_id)
|
17
16
|
end
|
18
17
|
|
19
18
|
attr_accessor :driver
|
20
19
|
attr_accessor :driver_name
|
21
|
-
attr_accessor :access_token
|
22
20
|
attr_accessor :subscription_id
|
23
21
|
end
|
24
22
|
end
|
@@ -4,43 +4,23 @@ class Chef
|
|
4
4
|
module Provisioning
|
5
5
|
module AzureRM
|
6
6
|
class Credentials
|
7
|
-
AZURE_SERVICE_PRINCIPAL = '1950a258-227b-4e31-a9cf-717495945fc2'
|
8
7
|
CONFIG_PATH = "#{ENV['HOME']}/.azure/credentials"
|
9
8
|
|
10
9
|
def initialize
|
11
10
|
config_file = ENV['AZURE_CONFIG_FILE'] || File.expand_path(CONFIG_PATH)
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
fail "No credentials loaded! Do you have a #{CONFIG_PATH} and a section [#{subscription_id}] within it?" \
|
18
|
-
unless @credentials[subscription_id]
|
19
|
-
fail "No username was found for subscription #{subscription_id}, please verify #{CONFIG_PATH}" \
|
20
|
-
unless @credentials[subscription_id]['username']
|
21
|
-
azure_authenticate(@credentials[subscription_id]['username'], @credentials[subscription_id]['password'])
|
22
|
-
end
|
23
|
-
|
24
|
-
# Do a user_impersonation to get an OAUTH2 access_token for further requests
|
25
|
-
# - Right now this means that the entire recipe must complete with 1 hour
|
26
|
-
# - of the token being issued (NB: the same token can be issued with that hour)
|
27
|
-
def azure_authenticate(username, password)
|
28
|
-
url = 'https://login.windows.net/Common/oauth2/token'
|
29
|
-
data = "resource=https%3A%2F%2Fmanagement.core.windows.net%2F&client_id=#{AZURE_SERVICE_PRINCIPAL}" \
|
30
|
-
"&grant_type=password&username=#{username}&scope=openid&password=#{password}"
|
31
|
-
response = http_post(url, data)
|
32
|
-
JSON.parse(response.body)['access_token']
|
11
|
+
if File.file?(config_file)
|
12
|
+
@credentials = IniFile.load(File.expand_path(config_file))
|
13
|
+
else
|
14
|
+
Chef::Log.warn "#{CONFIG_PATH} was not found or not accessible." unless File.file?(config_file)
|
15
|
+
end
|
33
16
|
end
|
34
17
|
|
35
|
-
def
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
response = http.request request
|
42
|
-
end
|
43
|
-
response
|
18
|
+
def azure_credentials_for_subscription(subscription_id)
|
19
|
+
tenant_id = ENV['AZURE_TENANT_ID'] || @credentials[subscription_id]['tenant_id']
|
20
|
+
client_id = ENV['AZURE_CLIENT_ID'] || @credentials[subscription_id]['client_id']
|
21
|
+
client_secret = ENV['AZURE_CLIENT_SECRET'] || @credentials[subscription_id]['client_secret']
|
22
|
+
token_provider = MsRestAzure::ApplicationTokenProvider.new(tenant_id, client_id, client_secret)
|
23
|
+
MsRest::TokenCredentials.new(token_provider)
|
44
24
|
end
|
45
25
|
|
46
26
|
def self.singleton
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chef-provisioning-azurerm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stuart Preston
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-09-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: chef
|
@@ -78,6 +78,20 @@ dependencies:
|
|
78
78
|
- - "~>"
|
79
79
|
- !ruby/object:Gem::Version
|
80
80
|
version: '2.0'
|
81
|
+
- !ruby/object:Gem::Dependency
|
82
|
+
name: azure_mgmt_resources
|
83
|
+
requirement: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - "~>"
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
type: :runtime
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - "~>"
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
81
95
|
- !ruby/object:Gem::Dependency
|
82
96
|
name: bundler
|
83
97
|
requirement: !ruby/object:Gem::Requirement
|