azure-profile 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGES +2 -0
- data/MANIFEST +11 -0
- data/README +93 -0
- data/Rakefile +29 -0
- data/azure-profile.gemspec +27 -0
- data/lib/azure/profile.rb +213 -0
- data/lib/azure/profile/subscription.rb +70 -0
- data/spec/azure.publishsettings +12 -0
- data/spec/azureProfile.json +17 -0
- data/spec/azure_profile_spec.rb +63 -0
- data/spec/azure_subscription_spec.rb +65 -0
- metadata +119 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 83513864d3a8bb9b76390fa0a8409634b9fa4fc2
|
4
|
+
data.tar.gz: 88f3bbd946b474ad2cea84fe95d5ed79ec07eb1d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2097b9adc3fd0b75adea22695ded5ac9e7d09c8000f3120a2a8388140d6c4f6a0238ac506341535b7b1aa8c2f8191d0c74b1116fee8fb82e1001fbaf51af09d2
|
7
|
+
data.tar.gz: 09c1277275db790024f1eaef15e7d8739eddbaab34a378800f12e054046387d231addec3c58bf43758f679635c52bb4f43346202fe87eedb680e4719154607a9
|
data/CHANGES
ADDED
data/MANIFEST
ADDED
data/README
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
= Description
|
2
|
+
A library for gathering Azure profile information.
|
3
|
+
|
4
|
+
= Prerequisites
|
5
|
+
* openssl
|
6
|
+
* json
|
7
|
+
* nokogiri
|
8
|
+
|
9
|
+
= Installation
|
10
|
+
gem install azure-profile
|
11
|
+
|
12
|
+
= Synopsis
|
13
|
+
require 'azure/profile'
|
14
|
+
|
15
|
+
# Assumes ~/.azure/azureProfile.json exists
|
16
|
+
prof = Azure::Profile.new
|
17
|
+
|
18
|
+
# Uses an existing publish settings file
|
19
|
+
prof = Azure::Profile.new(:settings_file => '/path/to/publishsettingsfile')
|
20
|
+
|
21
|
+
# Or the content of a settings file
|
22
|
+
prof = Azure::Profile.new(:content => IO.read('/path/to/settingsfile'))
|
23
|
+
|
24
|
+
p prof.subscriptions
|
25
|
+
p prof.default_subscription
|
26
|
+
|
27
|
+
# Using azure-profile in conjunction with the azure gem
|
28
|
+
require 'azure'
|
29
|
+
require 'azure/profile'
|
30
|
+
|
31
|
+
prof = Azure::Profile.new
|
32
|
+
dsub = prof.default.subscription
|
33
|
+
|
34
|
+
# The azure gem currently demands a file
|
35
|
+
pem_file = File.expand_path("~/.azure/azure.pem")
|
36
|
+
|
37
|
+
unless File.exists?(pem_file)
|
38
|
+
File.open(pem_file, 'w'){ |fh| fh.write dsub.management_certificate }
|
39
|
+
end
|
40
|
+
|
41
|
+
Azure.configure do |config|
|
42
|
+
config.management_certificate = pem_file
|
43
|
+
config.subscription_id = dsub.subscription_id
|
44
|
+
config.management_endpoint = dsub.management_endpoint
|
45
|
+
end
|
46
|
+
|
47
|
+
= Details
|
48
|
+
The azure-profile gem gathers and wraps your Azure subscription information.
|
49
|
+
Specifically, it will parse information out of your azureProfile.json file
|
50
|
+
if present. Alternatively, you can have it use a publishsettings file instead.
|
51
|
+
|
52
|
+
With that information you can pass the credentials of the subscription of
|
53
|
+
your choice to whatever Azure interface you're using, such as the azure gem.
|
54
|
+
|
55
|
+
= Getting a publishsettings file
|
56
|
+
If you want to download a publishsettings file, point your browser at:
|
57
|
+
|
58
|
+
https://manage.windowsazure.com/publishsettings/index
|
59
|
+
|
60
|
+
Login if you're not already logged in, and it should start a file download.
|
61
|
+
I recommend putting that file in $HOME/.azure and naming it
|
62
|
+
"azure.publishsettings" for future convenience.
|
63
|
+
|
64
|
+
If you're a powershell user, you can do Get-AzurePublishSettingsFile instead.
|
65
|
+
|
66
|
+
A publishsettings file is a simple XML file, so feel free to inspect it
|
67
|
+
at your convenience.
|
68
|
+
|
69
|
+
= Getting an azureProfile.json file
|
70
|
+
If you've installed and used the cross-platform command line interface, then
|
71
|
+
you should already have this file. If not, the best way to get one is to install
|
72
|
+
and login using the command line interface.
|
73
|
+
|
74
|
+
http://azure.microsoft.com/en-us/documentation/articles/xplat-cli/
|
75
|
+
|
76
|
+
= Future Plans
|
77
|
+
Allow the option to specify a username and password to automatically
|
78
|
+
retrieve a publishsettings file if one isn't found.
|
79
|
+
|
80
|
+
= Acknowledgements
|
81
|
+
This library possible courtesy of Red Hat, Inc.
|
82
|
+
|
83
|
+
= License
|
84
|
+
Artistic 2.0
|
85
|
+
|
86
|
+
== Warranty
|
87
|
+
This library is provided "as is" and without any express or
|
88
|
+
implied warranties, including, without limitation, the implied
|
89
|
+
warranties of merchantability and fitness for a particular purpose.
|
90
|
+
|
91
|
+
= Authors
|
92
|
+
* Daniel Berger
|
93
|
+
* Bronagh Sorota
|
data/Rakefile
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/clean'
|
3
|
+
require 'rake/testtask'
|
4
|
+
|
5
|
+
CLEAN.include('**/*.tar', '**/*.zip', '**/*.gz', '**/*.bz2')
|
6
|
+
CLEAN.include('**/*.rbc', '**/*.gem', '**/*.tmp')
|
7
|
+
|
8
|
+
namespace 'gem' do
|
9
|
+
desc 'Create the azure-profile gem'
|
10
|
+
task :create => [:clean] do
|
11
|
+
require 'rubygems/package'
|
12
|
+
spec = eval(IO.read('azure-profile.gemspec'))
|
13
|
+
Gem::Package.build(spec)
|
14
|
+
end
|
15
|
+
|
16
|
+
desc 'Install the azure-profile gem'
|
17
|
+
task :install => [:create] do
|
18
|
+
file = Dir["*.gem"].first
|
19
|
+
sh "gem install -l #{file}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
Rake::TestTask.new do |t|
|
24
|
+
t.test_files = ['spec/*.rb']
|
25
|
+
t.verbose = true
|
26
|
+
t.warning = true
|
27
|
+
end
|
28
|
+
|
29
|
+
task :default => :test
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
Gem::Specification.new do |spec|
|
4
|
+
spec.name = 'azure-profile'
|
5
|
+
spec.version = '1.0.0'
|
6
|
+
spec.authors = ['Daniel J. Berger', 'Bronagh Sorota']
|
7
|
+
spec.license = 'Artistic 2.0'
|
8
|
+
spec.homepage = 'http://github.com/djberg96/azure-profile'
|
9
|
+
spec.summary = 'An interface for Azure authentication information'
|
10
|
+
spec.test_file = 'spec/azure_profile_spec.rb'
|
11
|
+
spec.files = Dir['**/*'].delete_if{ |item| item.include?('git') }
|
12
|
+
|
13
|
+
spec.extra_rdoc_files = ['CHANGES', 'README', 'MANIFEST']
|
14
|
+
|
15
|
+
spec.add_dependency('json')
|
16
|
+
spec.add_dependency('nokogiri')
|
17
|
+
|
18
|
+
spec.add_development_dependency('rspec')
|
19
|
+
spec.add_development_dependency('rake')
|
20
|
+
|
21
|
+
spec.description = <<-EOF
|
22
|
+
This is a simple Ruby interface for gathering authentication and
|
23
|
+
subscription information for Windows Azure. It will automatically
|
24
|
+
gather subscription information based on a publishsettings file or
|
25
|
+
an azureProfile.json file.
|
26
|
+
EOF
|
27
|
+
end
|
@@ -0,0 +1,213 @@
|
|
1
|
+
require_relative 'profile/subscription'
|
2
|
+
|
3
|
+
module Azure
|
4
|
+
class Profile
|
5
|
+
# The version of the azure-profile library
|
6
|
+
VERSION = '1.0.0'
|
7
|
+
|
8
|
+
# The raw content of your publishsettings file
|
9
|
+
attr_accessor :content
|
10
|
+
|
11
|
+
# The path to your publishsettings file
|
12
|
+
attr_accessor :settings_file
|
13
|
+
|
14
|
+
# The path to your azureProfile.json file
|
15
|
+
attr_accessor :json_file
|
16
|
+
|
17
|
+
# Username for use with publishsettings file retrieval
|
18
|
+
attr_accessor :username
|
19
|
+
|
20
|
+
# Password for use with publishsettings file retrieval
|
21
|
+
attr_accessor :password
|
22
|
+
|
23
|
+
# A list of subscriptions associated with your profile
|
24
|
+
attr_reader :subscriptions
|
25
|
+
|
26
|
+
# Creates and returns a new Azure::Profile object. This will attempt to
|
27
|
+
# gather subscription information based on the options you pass to it.
|
28
|
+
#
|
29
|
+
# If you pass no options it will attempt to use the relevant environment
|
30
|
+
# variables to gather information. Specifically, it will look for the
|
31
|
+
# AZURE_MANAGEMENT_CERTIFICATE, AZURE_MANAGEMENT_ENDPOINT and the
|
32
|
+
# AZURE_SUBSCRIPTION_ID environment variables.
|
33
|
+
#
|
34
|
+
# If any of those are not set, or if you specify the :json_file option, it
|
35
|
+
# will try to read and parse your azureProfile.json file. By default it
|
36
|
+
# will look for this file in $HOME/.azure, but you may specify a different
|
37
|
+
# directory.
|
38
|
+
#
|
39
|
+
# If you pass the :settings_file option, it will use nokogiri to parse
|
40
|
+
# your publishsettings file. You must include the full path if you use
|
41
|
+
# this option.
|
42
|
+
#
|
43
|
+
# If you pass the :content option, which can be a string or an IO object,
|
44
|
+
# it will parse the the content as a string. This assumes XML format.
|
45
|
+
#
|
46
|
+
# FUTURE PLANS
|
47
|
+
#
|
48
|
+
# If you pass the :username and :password options, then it will attempt
|
49
|
+
# to download a publishsettings file from Microsoft to your $HOME/.azure
|
50
|
+
# directory, and will then parse that.
|
51
|
+
#
|
52
|
+
# Examples:
|
53
|
+
#
|
54
|
+
# require 'azure/subscription'
|
55
|
+
#
|
56
|
+
# # Default to using env variables or json file.
|
57
|
+
# prof = Azure::Profile.new
|
58
|
+
# p prof.subscriptions
|
59
|
+
#
|
60
|
+
# # Use a publishsettings file
|
61
|
+
# prof = Azure::Profile.new(:settings_file => "/Users/foo/azure.publishsettings")
|
62
|
+
# p prof.subscriptions
|
63
|
+
#
|
64
|
+
# # Use your MS credentials
|
65
|
+
# prof = Azure::Profile.new(:username => 'foo', :password => 'xxxxx')
|
66
|
+
# p prof.subscriptions
|
67
|
+
#
|
68
|
+
# # Pass a string or IO object
|
69
|
+
# prof = Azure::Profile.new(:content => IO.read("/Users/foo/azure.publishsettings"))
|
70
|
+
# prof = Azure::Profile.new(:content => File.open("/Users/foo/azure.publishsettings"))
|
71
|
+
#
|
72
|
+
def initialize(options = {})
|
73
|
+
@settings_file = options[:settings_file]
|
74
|
+
@json_file = options[:json_file] || "~/.azure/azureProfile.json"
|
75
|
+
@username = options[:username]
|
76
|
+
@password = options[:password]
|
77
|
+
@content = options[:content]
|
78
|
+
|
79
|
+
@subscriptions = []
|
80
|
+
|
81
|
+
env = get_env_info
|
82
|
+
|
83
|
+
@subscriptions << env if env
|
84
|
+
|
85
|
+
if @settings_file
|
86
|
+
@subscriptions << parse_settings(@settings_file)
|
87
|
+
elsif @content
|
88
|
+
@subscriptions << parse_settings(@content, false)
|
89
|
+
else
|
90
|
+
@subscriptions << parse_json_info
|
91
|
+
end
|
92
|
+
|
93
|
+
@subscriptions.flatten!
|
94
|
+
end
|
95
|
+
|
96
|
+
# Return the default subscription for the profile.
|
97
|
+
def default_subscription
|
98
|
+
@subscriptions.detect{ |s| s.default }
|
99
|
+
end
|
100
|
+
|
101
|
+
private
|
102
|
+
|
103
|
+
# Look for relevant environment variables. If they're found, then
|
104
|
+
# create a Subscription object using those.
|
105
|
+
#
|
106
|
+
def get_env_info
|
107
|
+
sub = nil
|
108
|
+
|
109
|
+
if ENV['AZURE_MANAGEMENT_CERTIFICATE'] ||
|
110
|
+
ENV['AZURE_MANAGEMENT_ENDPOINT'] ||
|
111
|
+
ENV['AZURE_SUBSCRIPTION_ID']
|
112
|
+
then
|
113
|
+
sub = Subscription.new
|
114
|
+
sub.subscription_id = ENV['AZURE_SUBSCRIPTION_ID']
|
115
|
+
sub.management_certificiate = ENV['AZURE_MANAGEMENT_CERTIFICATE']
|
116
|
+
sub.management_endpoint = ENV['AZURE_MANAGEMENT_ENDPOINT']
|
117
|
+
sub.source = "environment variables"
|
118
|
+
end
|
119
|
+
|
120
|
+
sub
|
121
|
+
end
|
122
|
+
|
123
|
+
# Parses a publishsettings file, or the raw XML.
|
124
|
+
#
|
125
|
+
def parse_settings(data, file = true)
|
126
|
+
require 'nokogiri'
|
127
|
+
require 'openssl'
|
128
|
+
require 'base64'
|
129
|
+
|
130
|
+
if file
|
131
|
+
doc = Nokogiri::XML(File.open(data))
|
132
|
+
else
|
133
|
+
doc = Nokogiri::XML(data)
|
134
|
+
end
|
135
|
+
|
136
|
+
xml = doc.xpath("//PublishData//PublishProfile//Subscription")
|
137
|
+
|
138
|
+
sub = Subscription.new
|
139
|
+
|
140
|
+
sub.management_endpoint = xml.attribute('ServiceManagementUrl').value
|
141
|
+
sub.subscription_id = xml.attribute('Id').value
|
142
|
+
sub.subscription_name = xml.attribute('Name').value
|
143
|
+
sub.default = true
|
144
|
+
|
145
|
+
if file
|
146
|
+
sub.source = @settings_file
|
147
|
+
else
|
148
|
+
sub.source = 'external'
|
149
|
+
end
|
150
|
+
|
151
|
+
raw = xml.attribute('ManagementCertificate').value
|
152
|
+
pkcs = OpenSSL::PKCS12.new(Base64.decode64(raw))
|
153
|
+
sub.management_certificate = pkcs.certificate.to_pem + pkcs.key.to_pem
|
154
|
+
|
155
|
+
sub
|
156
|
+
end
|
157
|
+
|
158
|
+
# Parses the Azure json profile file. This file should exist if you've
|
159
|
+
# ever used the command line interface.
|
160
|
+
#
|
161
|
+
def parse_json_info
|
162
|
+
require 'json'
|
163
|
+
|
164
|
+
data = IO.read(File.expand_path(@json_file))
|
165
|
+
json = JSON.parse(data, :create_additions => false)
|
166
|
+
|
167
|
+
array = []
|
168
|
+
|
169
|
+
if json['subscriptions']
|
170
|
+
json['subscriptions'].each{ |sub|
|
171
|
+
array << Subscription.new do |s|
|
172
|
+
s.source = @json_file
|
173
|
+
s.subscription_id = sub['id']
|
174
|
+
s.subscription_name = sub['name']
|
175
|
+
s.default = sub['isDefault'] || false
|
176
|
+
s.environment_name = sub['environmentName']
|
177
|
+
s.management_endpoint = sub['managementEndpointUrl']
|
178
|
+
s.registered_providers = sub['registeredProviders']
|
179
|
+
s.management_certificate = sub['managementCertificate']['cert'] +
|
180
|
+
sub['managementCertificate']['key']
|
181
|
+
end
|
182
|
+
}
|
183
|
+
end
|
184
|
+
|
185
|
+
array
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
if $0 == __FILE__
|
191
|
+
prof = Azure::Profile.new
|
192
|
+
dsub = prof.default_subscription
|
193
|
+
|
194
|
+
require 'azure'
|
195
|
+
|
196
|
+
# At the moment, the azure gem doesn't accept a string
|
197
|
+
pem_file = File.expand_path('~/.azure/azure.pem')
|
198
|
+
|
199
|
+
unless File.exists?(pem_file)
|
200
|
+
File.open(pem_file, 'w'){ |fh| fh.write dsub.management_certificate }
|
201
|
+
end
|
202
|
+
|
203
|
+
Azure.configure do |config|
|
204
|
+
config.subscription_id = dsub.subscription_id
|
205
|
+
config.management_certificate = pem_file
|
206
|
+
config.management_endpoint = dsub.management_endpoint
|
207
|
+
end
|
208
|
+
|
209
|
+
vms = Azure::VirtualMachineManagementService.new
|
210
|
+
vm = vms.get_virtual_machine('win2k8-test1', 'win2k8-test1')
|
211
|
+
|
212
|
+
p vm
|
213
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Azure
|
2
|
+
class Profile
|
3
|
+
# A class that represents an invididual subscription with an Azure profile.
|
4
|
+
class Subscription
|
5
|
+
# Azure subscription ID.
|
6
|
+
attr_accessor :subscription_id
|
7
|
+
|
8
|
+
# Azure subscription name, e.g. "Free Trial"
|
9
|
+
attr_accessor :subscription_name
|
10
|
+
|
11
|
+
# Azure certificate, a combination of the cert + key
|
12
|
+
attr_accessor :management_certificate
|
13
|
+
|
14
|
+
# Returns whether or not this is a default subscription
|
15
|
+
attr_accessor :default
|
16
|
+
|
17
|
+
# An array of registered providers
|
18
|
+
attr_accessor :registered_providers
|
19
|
+
|
20
|
+
# Azure environment name, e.g. "AzureCloud"
|
21
|
+
attr_accessor :environment_name
|
22
|
+
|
23
|
+
# Azure endpoint. The default is https://management.core.windows.net
|
24
|
+
attr_accessor :management_endpoint
|
25
|
+
|
26
|
+
# The source of the subscription, e.g. "~/.azure/azureProfile.json"
|
27
|
+
attr_accessor :source
|
28
|
+
|
29
|
+
DEFAULT_MANAGEMENT_ENDPOINT = "https://management.core.windows.net"
|
30
|
+
|
31
|
+
# Creates and returns a new Subscription object. If a block is given
|
32
|
+
# then the object is yielded to the block.
|
33
|
+
#
|
34
|
+
# Example:
|
35
|
+
#
|
36
|
+
# # These values are for demonstration purposes only
|
37
|
+
# Subscription.new do |s|
|
38
|
+
# s.subscription_id = 'abc-123-xyz'
|
39
|
+
# s.subscription_name = 'My Subscription'
|
40
|
+
# s.source = 'me'
|
41
|
+
# s.default = false
|
42
|
+
# s.management_certificate = generate_my_cert(Etc.getlogin)
|
43
|
+
# s.environment_name = 'MyEnvironment'
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
# If no :management_endpoint is provided, then it will default to using
|
47
|
+
# Subscription::DEFAULT_MANAGEMENT_ENDPOINT. If no :source is provided,
|
48
|
+
# then it will default to 'ruby'. If no :default is provided, it will
|
49
|
+
# default to false. If no :environment_name is provided, it will default
|
50
|
+
# to 'AzureCloud'.
|
51
|
+
#
|
52
|
+
# There is no default for the :registered providers or
|
53
|
+
# :management_certificate accessors. You must provide those. The certificate
|
54
|
+
# should be a combination of the cert and key so that you can pass its value
|
55
|
+
# directly to another interface, such as the azure gem.
|
56
|
+
#
|
57
|
+
# Note that you will not normally create Subscription objects directly.
|
58
|
+
# The Azure::Profile class will generate them and pass them back to you.
|
59
|
+
#
|
60
|
+
def initialize
|
61
|
+
yield self if block_given?
|
62
|
+
|
63
|
+
@management_endpoint ||= DEFAULT_MANAGEMENT_ENDPOINT
|
64
|
+
@source ||= 'ruby'
|
65
|
+
@default ||= false
|
66
|
+
@environment_name ||= 'AzureCloud'
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
2
|
+
<PublishData>
|
3
|
+
<PublishProfile
|
4
|
+
SchemaVersion="2.0"
|
5
|
+
PublishMethod="AzureServiceManagementAPI">
|
6
|
+
<Subscription
|
7
|
+
ServiceManagementUrl="https://management.core.windows.net"
|
8
|
+
Id="b135322f-9d7e-4975-1234-237b85343c3c"
|
9
|
+
Name="Free Trial"
|
10
|
+
ManagementCertificate="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" />
|
11
|
+
</PublishProfile>
|
12
|
+
</PublishData>
|
@@ -0,0 +1,17 @@
|
|
1
|
+
{
|
2
|
+
"environments": [],
|
3
|
+
"subscriptions": [
|
4
|
+
{
|
5
|
+
"id": "b135322f-9d7e-4975-1234-237b85343c3c",
|
6
|
+
"name": "Free Trial",
|
7
|
+
"managementCertificate": {
|
8
|
+
"key": "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAtIdOgHPrIY/0miErcP7HsafhDVYS/kFMVbqKdeaoNot8Dg+9\r\ngL73+593TUHPspbRlRJ3+84ONQwE7am3HVk/SkudgptSZSn5P9gS+W+X4SKO4FG5\r\n0Mc4sNgnx8JMtGhYPTk4CTXVRju7gCZFsvtWPWx8uCCEHCszC+JZYMspNvs2Shzy\r\nTYb1C3mLmbJf9y/uTIggQpZnq8/TJZanadL+yGGFaP6bmqyHb4mx9gn5sk0tF1/Q\r\nr+HeFag6jwVbiwuIFIVDWqvsFjJ6VHunQcNLe9t5pEMjfpnPJkQ8geYNVLcwvU0w\r\neHgKe9N4YO9+VCJKxvgWMq41Rw99xw0M1RgdUQIDAQABAoIBABYxXJGOvoj8lha1\r\nDW65iYHR6CkgK9tRGnHfCeq60XLMJLLjVTnssBZhKRTIqoBzST5E3BZq40T67mer\r\noZjUagMHhuxhjQhl96/VL6b1pKOPAKa7sUbE2PeniQNmA9E5UyCqpjR+p1J4ISGc\r\nwtyBCJ3qNm5Zw/flCSRUvgVX0GAjXlyzjRLR6TbHYgCa4UmQg/nK8z6XR821HnrG\r\n6QVYZ7qkWTi1o9XDwl0lt6I65c5vx+CW9CoWhpjMk/RBQMDWbaUhwgw09xveXyRo\r\n3G2yClPnN+yO4DZ+jj9IeAZ4y4fdHbnXc+KiulNIxFY2v1933APKoESlVFtIBT+p\r\nZ4hybYkCgYEAwAv3dMq90/i0Zdjs3jiNXaayW2zURfu435VkdVmBIpOBDMEorPZU\r\n/gPjTW/IQxzn4S4SFpL1b3vQyGBknqzwMFInOTmZovkDcP8Hclfy4Fg1N+PAoiwX\r\n/js0Qy6iXzgZFyx3Icu/XaQwOqBe7hQcp7/bu01QChgo9c1wsByicpkCgYEA8KVp\r\nChN5Wk9j0sbXHx/efNODmvI4VpoJRjSkxF86RM8D7b+7IOSxAulcj/BXP2R8sWCW\r\ntdV8s3J+l0HPOnrHsQN5PskdFD/e72FowcVBADrS7Rs0y2bwGYmQyc2zE1idv1uN\r\nNa4GSHjt12CgBPD0SMEAoyjnF2le3tOTOoX6a3kCgYAWEwoNjaRGMiciMc4AOQXe\r\nxuNnaNn5dVaptHVIm9IhFE1YFvfC8cmRLQc6hmfBdxgcJPyFRb0aZGP6NEI8jupI\r\n05iYlktXlUHVAitr9DoBmYH8e5xPx7u2SD3Ynwqg4UTZCg5jfxTvAYldo8NloEAu\r\n8/mgzOEvV9mVb1jNlW0CuQKBgQCjnAIvLJBL+z/mFPQ7IAK3IWMPnHD7SBzYE4CW\r\nVhwanhiQstM6COHkFd6tqfzXh61TN1Uf6TawFj7E/aQzoThVPARZ0IgptUcPv01m\r\nuIJ58oRnWiDpzWGeKy46VdTTaWNOr6LxBREWgslJrlL9KQkc0cNqKqv6+dPbcUNe\r\n/aoFGQKBgEeXYDpEC11Y+WHaPWx/oRP2aMh9lSbRHINNdcc6uGSS9ywTb+ObJVgg\r\nYhjAZ04pb9wZLSmLLt2NDBC3OEIMl920Ah2OxVWNbvuglubqmtcdBJtCbyFDtfhr\r\nrHujJHJ+F4VSwo/fdHmVg53LG3Pdacte/IydqOp6SkcZS30ZPn/w\r\n-----END RSA PRIVATE KEY-----\n",
|
9
|
+
"cert": "-----BEGIN CERTIFICATE-----\nMIICxDCCAaygAwIBAgIQY4/XKHqDZo5JR5QZ8BHXCTANBgkqhkiG9w0BAQUFADAe\r\nMRwwGgYDVQQDExNXaW5kb3dzIEF6dXJlIFRvb2xzMB4XDTE1MDUwNjEzNDkyOFoX\r\nDTE2MDUwNjEzNDkyOFowHjEcMBoGA1UEAxMTV2luZG93cyBBenVyZSBUb29sczCC\r\nASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALSHToBz6yGP9JohK3D+x7Gn\r\n4Q1WEv5BTFW6inXmqDaLfA4PvYC+9/ufd01Bz7KW0ZUSd/vODjUMBO2ptx1ZP0pL\r\nnYKbUmUp+T/YEvlvl+EijuBRudDHOLDYJ8fCTLRoWD05OAk11UY7u4AmRbL7Vj1s\r\nfLgghBwrMwviWWDLKTb7Nkoc8k2G9Qt5i5myX/cv7kyIIEKWZ6vP0yWWp2nS/shh\r\nhWj+m5qsh2+JsfYJ+bJNLRdf0K/h3hWoOo8FW4sLiBSFQ1qr7BYyelR7p0HDS3vb\r\neaRDI36ZzyZEPIHmDVS3ML1NMHh4CnvTeGDvflQiSsb4FjKuNUcPfccNDNUYHVEC\r\nAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAMlUjsEp2X/jW7EZUH00xV0x90sfaRtcv\r\nPStfCmSbwtmjE4z3fHbUUFHEnvPCq5Y9CQxfoyYDMiOpQJ+dmD6RcKeGLAHgrLq3\r\n60K7NkbD5kxbAa3l3K3JN/M0w5HFmHt0vjLfykPy76eE2RtyOVkb0f/klASWc1Oy\r\nNw05PuVFgXKU7PSnIbGknHC8MnBeGOcpPDdxGk3hplfx5cqThdZn122nrtbFgovM\r\n0u3FZVarHftlFH4L2hp6G4NUaVzkxgj7VYTEqwbD+ahP6iaqa0d3a++q0Py/hcld\r\n8anOrg5W+my2P/q0iAUOcOQ8iFfvbU5pAueEtgw8VVUfaYWOUX8czQ==\n-----END CERTIFICATE-----\n"
|
10
|
+
},
|
11
|
+
"isDefault": true,
|
12
|
+
"registeredProviders": [],
|
13
|
+
"environmentName": "AzureCloud",
|
14
|
+
"managementEndpointUrl": "https://management.core.windows.net"
|
15
|
+
}
|
16
|
+
]
|
17
|
+
}
|
@@ -0,0 +1,63 @@
|
|
1
|
+
#########################################################
|
2
|
+
# azure_profile_spec.rb
|
3
|
+
#
|
4
|
+
# Specs for the Azure::Profile class.
|
5
|
+
#########################################################
|
6
|
+
require 'rspec/autorun'
|
7
|
+
require 'azure/profile'
|
8
|
+
|
9
|
+
describe "profile" do
|
10
|
+
before(:all) do
|
11
|
+
@json_file = File.join(File.dirname(__FILE__), 'azureProfile.json')
|
12
|
+
@settings_file = File.join(File.dirname(__FILE__), 'azure.publishsettings')
|
13
|
+
end
|
14
|
+
|
15
|
+
it "has a VERSION constant set to the expected value" do
|
16
|
+
Azure::Profile::VERSION.should eq("1.0.0")
|
17
|
+
end
|
18
|
+
|
19
|
+
after(:all) do
|
20
|
+
@json_file = nil
|
21
|
+
@settings_file = nil
|
22
|
+
end
|
23
|
+
|
24
|
+
context "using publishsettings file" do
|
25
|
+
before(:all) do
|
26
|
+
@profile = Azure::Profile.new(:settings_file => @settings_file)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "has a settings_file accessor and it is set to the expected value" do
|
30
|
+
@profile.should respond_to(:settings_file)
|
31
|
+
@profile.settings_file.should eq(@settings_file)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "sets the default subscription" do
|
35
|
+
@profile.should respond_to(:default_subscription)
|
36
|
+
@profile.default_subscription.should be_kind_of(Azure::Profile::Subscription)
|
37
|
+
end
|
38
|
+
|
39
|
+
after(:all) do
|
40
|
+
@profile = nil
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context "using json file" do
|
45
|
+
before(:all) do
|
46
|
+
@profile = Azure::Profile.new(:json_file => @json_file)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "has a json_file accessor and it is set to the expected value" do
|
50
|
+
@profile.should respond_to(:json_file)
|
51
|
+
@profile.json_file.should eq(@json_file)
|
52
|
+
end
|
53
|
+
|
54
|
+
it "sets the default subscription" do
|
55
|
+
@profile.should respond_to(:default_subscription)
|
56
|
+
@profile.default_subscription.should be_kind_of(Azure::Profile::Subscription)
|
57
|
+
end
|
58
|
+
|
59
|
+
after(:all) do
|
60
|
+
@profile = nil
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
#########################################################
|
2
|
+
# azure_subscription_spec.rb
|
3
|
+
#
|
4
|
+
# Specs for the Azure::Profile::Subscription class.
|
5
|
+
#########################################################
|
6
|
+
require 'rspec/autorun'
|
7
|
+
require 'azure/profile'
|
8
|
+
|
9
|
+
describe "subscription" do
|
10
|
+
before(:all) do
|
11
|
+
@default_endpoint = "https://management.core.windows.net"
|
12
|
+
end
|
13
|
+
|
14
|
+
before(:each) do
|
15
|
+
@sub = Azure::Profile::Subscription.new
|
16
|
+
end
|
17
|
+
|
18
|
+
it "has a subscription_id accessor" do
|
19
|
+
@sub.should respond_to(:subscription_id)
|
20
|
+
@sub.subscription_id.should be_nil
|
21
|
+
end
|
22
|
+
|
23
|
+
it "has a subscription_name accessor" do
|
24
|
+
@sub.should respond_to(:subscription_name)
|
25
|
+
@sub.subscription_name.should be_nil
|
26
|
+
end
|
27
|
+
|
28
|
+
it "has a management_certificate accessor" do
|
29
|
+
@sub.should respond_to(:management_certificate)
|
30
|
+
@sub.management_certificate.should be_nil
|
31
|
+
end
|
32
|
+
|
33
|
+
it "has a default accessor that defaults to false" do
|
34
|
+
@sub.should respond_to(:default)
|
35
|
+
@sub.default.should be_false
|
36
|
+
end
|
37
|
+
|
38
|
+
it "has a registered_providers accessor" do
|
39
|
+
@sub.should respond_to(:registered_providers)
|
40
|
+
@sub.registered_providers.should be_nil
|
41
|
+
end
|
42
|
+
|
43
|
+
it "has an environment_name accessor with a default value" do
|
44
|
+
@sub.should respond_to(:environment_name)
|
45
|
+
@sub.environment_name.should eq("AzureCloud")
|
46
|
+
end
|
47
|
+
|
48
|
+
it "has a management_endpoint accessor with a default value" do
|
49
|
+
@sub.should respond_to(:management_endpoint)
|
50
|
+
@sub.management_endpoint.should eq(@default_endpoint)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "has a source accessor with a default value" do
|
54
|
+
@sub.should respond_to(:source)
|
55
|
+
@sub.source.should eq("ruby")
|
56
|
+
end
|
57
|
+
|
58
|
+
after(:each) do
|
59
|
+
@sub = nil
|
60
|
+
end
|
61
|
+
|
62
|
+
after(:all) do
|
63
|
+
@default_endpoint = nil
|
64
|
+
end
|
65
|
+
end
|
metadata
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: azure-profile
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Daniel J. Berger
|
8
|
+
- Bronagh Sorota
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2015-05-13 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: json
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ">="
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '0'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '0'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: nokogiri
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: rspec
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: rake
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
description: |2
|
71
|
+
This is a simple Ruby interface for gathering authentication and
|
72
|
+
subscription information for Windows Azure. It will automatically
|
73
|
+
gather subscription information based on a publishsettings file or
|
74
|
+
an azureProfile.json file.
|
75
|
+
email:
|
76
|
+
executables: []
|
77
|
+
extensions: []
|
78
|
+
extra_rdoc_files:
|
79
|
+
- CHANGES
|
80
|
+
- README
|
81
|
+
- MANIFEST
|
82
|
+
files:
|
83
|
+
- CHANGES
|
84
|
+
- MANIFEST
|
85
|
+
- README
|
86
|
+
- Rakefile
|
87
|
+
- azure-profile.gemspec
|
88
|
+
- lib/azure/profile.rb
|
89
|
+
- lib/azure/profile/subscription.rb
|
90
|
+
- spec/azure.publishsettings
|
91
|
+
- spec/azureProfile.json
|
92
|
+
- spec/azure_profile_spec.rb
|
93
|
+
- spec/azure_subscription_spec.rb
|
94
|
+
homepage: http://github.com/djberg96/azure-profile
|
95
|
+
licenses:
|
96
|
+
- Artistic 2.0
|
97
|
+
metadata: {}
|
98
|
+
post_install_message:
|
99
|
+
rdoc_options: []
|
100
|
+
require_paths:
|
101
|
+
- lib
|
102
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '0'
|
107
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - ">="
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
112
|
+
requirements: []
|
113
|
+
rubyforge_project:
|
114
|
+
rubygems_version: 2.4.6
|
115
|
+
signing_key:
|
116
|
+
specification_version: 4
|
117
|
+
summary: An interface for Azure authentication information
|
118
|
+
test_files:
|
119
|
+
- spec/azure_profile_spec.rb
|