Skip to content
This repository was archived by the owner on Jan 11, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 9 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,14 +150,10 @@ The following lines should be used to instantiate a profile client:

```ruby
# Provide credentials
provider = MsRestAzure::ApplicationTokenProvider.new(
ENV['AZURE_TENANT_ID'],
ENV['AZURE_CLIENT_ID'],
ENV['AZURE_CLIENT_SECRET'])
credentials = MsRest::TokenCredentials.new(provider)

options = {
credentials: credentials,
tenant_id: ENV['AZURE_TENANT_ID'],
client_id: ENV['AZURE_CLIENT_ID'],
client_secret: ENV['AZURE_CLIENT_SECRET'],
subscription_id: ENV['AZURE_SUBSCRIPTION_ID']
}

Expand Down Expand Up @@ -195,14 +191,10 @@ The following lines should be used to instantiate a profile client:

```ruby
# Provide credentials
provider = MsRestAzure::ApplicationTokenProvider.new(
ENV['AZURE_TENANT_ID'],
ENV['AZURE_CLIENT_ID'],
ENV['AZURE_CLIENT_SECRET'])
credentials = MsRest::TokenCredentials.new(provider)

options = {
credentials: credentials,
tenant_id: ENV['AZURE_TENANT_ID'],
client_id: ENV['AZURE_CLIENT_ID'],
client_secret: ENV['AZURE_CLIENT_SECRET'],
subscription_id: ENV['AZURE_SUBSCRIPTION_ID']
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would our guidelines from before profile changes not work for initializing credentials, I believe we were doing:

 provider = MsRestAzure::ApplicationTokenProvider.new(
        ENV['AZURE_TENANT_ID'],
        ENV['AZURE_CLIENT_ID'],
        ENV['AZURE_CLIENT_SECRET'])
    credentials = MsRest::TokenCredentials.new(provider)
    @client = Azure::ARM::Resources::ResourceManagementClient.new(credentials)
    @client.subscription_id = @subscription_id

If so, should we leave them as they were, just updating the namespace for ResourceManagementClient? so we demonstrate the minimum change?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW, after this PR is done, we'd need to re-update the samples that were updated with the last release too.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The detailed explanation would be that we always want the user (of the SDK) to provide us with the tenant_id, client_id, client_secret and subscription_id. There is no escaping that. The credentials is just a derived value from these. The user may or may not provide it.

But, when you think about it, why would a user want to provide a derived value when he/she is supplying the original values anyway? That is the reason, I am updating the examples in readme and removed the credentials. But, if a user wants to provide it, then he is free to do that.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So... Credentials are not a bad thing to provide. This abstraction allows any token provider to be used.

Expand Down Expand Up @@ -242,14 +234,10 @@ The following lines should be used to instantiate a profile client:

```ruby
# Provide credentials
provider = MsRestAzure::ApplicationTokenProvider.new(
ENV['AZURE_TENANT_ID'],
ENV['AZURE_CLIENT_ID'],
ENV['AZURE_CLIENT_SECRET'])
credentials = MsRest::TokenCredentials.new(provider)

options = {
credentials: credentials,
tenant_id: ENV['AZURE_TENANT_ID'],
client_id: ENV['AZURE_CLIENT_ID'],
client_secret: ENV['AZURE_CLIENT_SECRET'],
subscription_id: ENV['AZURE_SUBSCRIPTION_ID']
}

Expand Down
6 changes: 6 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,9 @@ namespace :arm do
# bundle exec ruby profile_generator_client.rb --dir_metadata=dir_metadata.json --profile=profiles.json
command = "#{get_base_profile_generation_cmd}#{get_profile_spec_files_folder}/#{PROFILE_METADATA[:azure_sdk]}"
execute_and_stream(command)

FileUtils.cp("#{__dir__}/generators/profilegen/src/resources/common/configurable.rb", "#{__dir__}/azure_sdk/lib/common/configurable.rb")
FileUtils.cp("#{__dir__}/generators/profilegen/src/resources/common/default.rb", "#{__dir__}/azure_sdk/lib/common/default.rb")
end

desc 'Regen individual profiles'
Expand All @@ -183,6 +186,9 @@ namespace :arm do
# bundle exec ruby profile_generator_client.rb --dir_metadata=dir_metadata.json --profile=authorization_profiles.json
command = "#{get_base_profile_generation_cmd}#{get_profile_spec_files_folder}/#{profile_spec_file}"
execute_and_stream(command)

FileUtils.cp("#{__dir__}/generators/profilegen/src/resources/common/configurable.rb", "#{__dir__}/management/#{sdk}/lib/profiles/common/configurable.rb")
FileUtils.cp("#{__dir__}/generators/profilegen/src/resources/common/default.rb", "#{__dir__}/management/#{sdk}/lib/profiles/common/default.rb")
end
end
end
Expand Down
84 changes: 84 additions & 0 deletions generators/profilegen/src/resources/common/configurable.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# encoding: utf-8
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.

module Azure::Common
# The Azure::Common::Configurable module provides basic configuration for Azure activities.
module Configurable
# @return [String] Azure tenant id (also known as domain).
attr_accessor :tenant_id

# @return [String] Azure client id.
attr_accessor :client_id

# @return [String] Azure secret key.
attr_accessor :client_secret

# @return [String] Azure subscription id.
attr_accessor :subscription_id

# @return [MsRestAzure::ActiveDirectoryServiceSettings] Azure active directory service settings.
attr_accessor :active_directory_settings

# @return [MsRest::ServiceClientCredentials] credentials to authorize HTTP requests made by the service client.
attr_accessor :credentials

class << self
#
# List of configurable keys for {Azure::Common::Client}.
# @return [Array] of option keys.
#
def keys
@keys ||= [:tenant_id, :client_id, :client_secret, :subscription_id, :active_directory_settings]
end
end

#
# Set configuration options using a block.
#
def configure
yield self
end

#
# Resets the configurable options to provided options or defaults.
# This will also creates MsRest::TokenCredentials to be used for subsequent Azure Resource Manager clients.
#
def reset!(options = {})
Azure::Common::Configurable.keys.each do |key|
default_value = Azure::Common::Default.options[key]
instance_variable_set(:"@#{key}", options.fetch(key, default_value))
end

default_value = get_credentials(self.tenant_id, self.client_id, self.client_secret, self.active_directory_settings)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this needed?
if credentials are not passed in the options, should the "fetch" above get "credentials" from Configurable and set the value to the same thing that "get_credentials" below is doing?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder why we need to get credentials in Configurable and remove it from Default, where it was.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned in the previous comment, the user may or may not provide credentials in the options. If he provides it, we will use it. Else, we will derive it from the other values supplied.

The 2 fetch are different. The first one (in setup_options) is getting the credentials from the default value and the second one is from the user supplied values (not the environment variables).

instance_variable_set(:"@credentials", options.fetch(:credentials, default_value))

self
end

def config
self
end

private

#
# configures configurable options to default values
#
def setup_options

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this be called setup_default_options?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. WIll change the name and regen in a few minutes

opts = {}
Azure::Common::Configurable.keys.map do |key|
opts[key] = Azure::Common::Default.options[key]
end
opts[:credentials] = get_credentials(opts[:tenant_id], opts[:client_id], opts[:client_secret], opts[:active_directory_settings])
opts
end

def get_credentials(tenant_id, client_id, client_secret, active_directory_settings)
MsRest::TokenCredentials.new(
MsRestAzure::ApplicationTokenProvider.new(
tenant_id, client_id, client_secret, active_directory_settings))
end

end
end
57 changes: 57 additions & 0 deletions generators/profilegen/src/resources/common/default.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# encoding: utf-8
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.

module Azure::Common
module Default
class << self
#
# Default Azure Tenant Id.
# @return [String] Azure Tenant Id.
#
def tenant_id
ENV['AZURE_TENANT_ID']
end

#
# Default Azure Client Id.
# @return [String] Azure Client Id.
#
def client_id
ENV['AZURE_CLIENT_ID']
end

#
# Default Azure Client Secret.
# @return [String] Azure Client Secret.
#
def client_secret
ENV['AZURE_CLIENT_SECRET']
end

#
# Default Azure Subscription Id.
# @return [String] Azure Subscription Id.
#
def subscription_id
ENV['AZURE_SUBSCRIPTION_ID']
end

#
# Default Azure Active Directory Service Settings.
# @return [MsRestAzure::ActiveDirectoryServiceSettings] Azure Active Directory Service Settings.
#
def active_directory_settings
MsRestAzure::ActiveDirectoryServiceSettings.get_azure_settings
end

#
# Configuration options.
# @return [Hash] Configuration options.
#
def options
Hash[Azure::Common::Configurable.keys.map { |key| [key, send(key)]}]
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ module Azure::Profiles::<%= @profile_name %>::Mgmt
<%- else -%>
class Client
<%- end -%>
include Azure::ARM::Configurable
include Azure::Common::Configurable

<%- if !@individual_gem_profile -%>
attr_reader <% @class_names.each_with_index do |class_name, index| %> :<%= class_name.gsub(/([a-z\d])([A-Z])/,'\1_\2').downcase %><% if index != @class_names.length - 1 %>,<% end %><% end %>
Expand All @@ -57,7 +57,7 @@ module Azure::Profiles::<%= @profile_name %>::Mgmt

def credentials
if @credentials.nil?
self.active_directory_settings ||= Azure::ARM::Default.active_directory_settings
self.active_directory_settings ||= Azure::Common::Default.active_directory_settings

@credentials = MsRest::TokenCredentials.new(
MsRestAzure::ApplicationTokenProvider.new(
Expand Down