Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CHEF-2414 remove azure depedency #745

Open
wants to merge 4 commits into
base: train-4.0.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
15 changes: 0 additions & 15 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,3 @@ updates:
- dependency-name: "googleauth"
versions:
- ">=0.12"
- dependency-name: "azure_mgmt_resources"
versions:
- ">=0.16"
- dependency-name: "azure_mgmt_security"
versions:
- ">=0.19"
- dependency-name: "azure_mgmt_storage"
versions:
- ">=0.19"
- dependency-name: "azure_mgmt_key_vault"
versions:
- ">=0.18"
- dependency-name: "azure_graph_rbac"
versions:
- ">=0.17"
112 changes: 3 additions & 109 deletions lib/train/transports/azure.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
require "train/plugins"
require "ms_rest_azure"
require "azure_mgmt_resources"
require "azure_graph_rbac"
require "azure_mgmt_key_vault"
require "socket" unless defined?(Socket)
require "timeout" unless defined?(Timeout)
require "train/transports/helpers/azure/file_credentials"
require "train/transports/clients/azure/graph_rbac"
require "train/transports/clients/azure/vault"

module Train::Transports
class Azure < Train.plugin(1)
Expand All @@ -16,7 +10,6 @@ class Azure < Train.plugin(1)
option :client_id, default: ENV["AZURE_CLIENT_ID"]
option :client_secret, default: ENV["AZURE_CLIENT_SECRET"]
option :subscription_id, default: ENV["AZURE_SUBSCRIPTION_ID"]
option :msi_port, default: ENV["AZURE_MSI_PORT"] || "50342"

# This can provide the client id and secret
option :credentials_file, default: ENV["AZURE_CRED_FILE"]
Expand All @@ -25,6 +18,7 @@ def connection(_ = nil)
@connection ||= Connection.new(@options)
end

# @note all logic in this class is kept only to be moved later into inspec-azure
class Connection < BaseConnection
attr_reader :options

Expand All @@ -45,132 +39,32 @@ def initialize(options)
options[:credentials_file] = DEFAULT_FILE if options[:credentials_file].nil?
@options.merge!(Helpers::Azure::FileCredentials.parse(**@options))
end

@options[:msi_port] = @options[:msi_port].to_i unless @options[:msi_port].nil?

# additional platform details
release = Gem.loaded_specs["azure_mgmt_resources"].version
@platform_details = { release: "azure_mgmt_resources-v#{release}" }

connect
end

def platform
force_platform!("azure", @platform_details)
end

def azure_client(klass = ::Azure::Resources::Profiles::Latest::Mgmt::Client, opts = {})
# @note klass needs to be overriden to accept resource management class
def azure_client(klass = nil, opts = {})
if cache_enabled?(:api_call)
return @cache[:api_call][klass.to_s.to_sym] unless @cache[:api_call][klass.to_s.to_sym].nil?
end

if klass == ::Azure::Resources::Profiles::Latest::Mgmt::Client
@credentials[:base_url] = MsRestAzure::AzureEnvironments::AzureCloud.resource_manager_endpoint_url
elsif klass == ::Azure::GraphRbac::Profiles::Latest::Client
client = GraphRbac.client(@credentials)
elsif klass == ::Azure::KeyVault::Profiles::Latest::Mgmt::Client
client = Vault.client(opts[:vault_name], @credentials)
end

client ||= klass.new(@credentials)

# Cache if enabled
@cache[:api_call][klass.to_s.to_sym] ||= client if cache_enabled?(:api_call)

client
end

def connect
if msi_auth?
# this needs set for azure cloud to authenticate
ENV["MSI_VM"] = "true"
provider = ::MsRestAzure::MSITokenProvider.new(@options[:msi_port])
else
provider = ::MsRestAzure::ApplicationTokenProvider.new(
@options[:tenant_id],
@options[:client_id],
@options[:client_secret]
)
end

@credentials = {
credentials: ::MsRest::TokenCredentials.new(provider),
subscription_id: @options[:subscription_id],
tenant_id: @options[:tenant_id],
}
@credentials[:client_id] = @options[:client_id] unless @options[:client_id].nil?
@credentials[:client_secret] = @options[:client_secret] unless @options[:client_secret].nil?
end

def uri
"azure://#{@options[:subscription_id]}"
end

# Returns the api version for the specified resource type
#
# If an api version has been specified in the options then the apis version table is updated
# with that value and it is returned
#
# However if it is not specified, or multiple types are being interrogated then this method
# will interrogate Azure for each of the types versions and pick the latest one. This is added
# to the apis table so that it can be retrieved quickly again of another one of those resources
# is encountered again in the resource collection.
#
# @param string resource_type The resource type for which the API is required
# @param hash options Options have that have been passed to the resource during the test.
# @option opts [String] :group_name Resource group name
# @option opts [String] :type Azure resource type
# @option opts [String] :name Name of specific resource to look for
# @option opts [String] :apiversion If looking for a specific item or type specify the api version to use
#
# @return string API Version of the specified resource type
def get_api_version(resource_type, options)
# if an api version has been set in the options, add to the apis hashtable with
# the resource type
if options[:apiversion]
@apis[resource_type] = options[:apiversion]
else
# only attempt to get the api version from Azure if the resource type
# is not present in the apis hashtable
unless @apis.key?(resource_type)

# determine the namespace for the resource type
namespace, type = resource_type.split(%r{/})

client = azure_client(::Azure::Resources::Profiles::Latest::Mgmt::Client)
provider = client.providers.get(namespace)

# get the latest API version for the type
# assuming that this is the first one in the list
api_versions = (provider.resource_types.find { |v| v.resource_type == type }).api_versions
@apis[resource_type] = api_versions[0]
end
end

# return the api version for the type
@apis[resource_type]
end

def unique_identifier
options[:subscription_id] || options[:tenant_id]
end

def msi_auth?
@options[:client_id].nil? && @options[:client_secret].nil? && port_open?(@options[:msi_port])
end

private

def port_open?(port, seconds = 3)
Timeout.timeout(seconds) do
TCPSocket.new("localhost", port).close
true
rescue SystemCallError
false
end
rescue Timeout::Error
false
end
end
end
end
33 changes: 0 additions & 33 deletions lib/train/transports/clients/azure/graph_rbac.rb

This file was deleted.

39 changes: 0 additions & 39 deletions lib/train/transports/clients/azure/vault.rb

This file was deleted.

61 changes: 0 additions & 61 deletions test/unit/transports/azure_test.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
require "helper"

# Required because this test file acesses classes under Azure::
require "azure_mgmt_resources"
require "azure_graph_rbac"
require "azure_mgmt_key_vault"

describe "azure transport" do
def transport(options = nil)
ENV["AZURE_TENANT_ID"] = "test_tenant_id"
Expand Down Expand Up @@ -76,62 +71,6 @@ def initialize(hash)
_(client.is_a?(AzureResource)).must_equal true
_(cache[:api_call].count).must_equal 0
end

it "can use azure_client default client" do
management_api_client = Azure::Resources::Profiles::Latest::Mgmt::Client
client = connection.azure_client
_(client.class).must_equal management_api_client
end

it "can use azure_client graph client" do
graph_api_client = Azure::GraphRbac::Profiles::Latest::Client
client = connection.azure_client(graph_api_client)
_(client.class).must_equal graph_api_client
end

it "can use azure_client vault client" do
vault_api_client = ::Azure::KeyVault::Profiles::Latest::Mgmt::Client
client = connection.azure_client(vault_api_client, vault_name: "Test Vault")
_(client.class).must_equal vault_api_client
end

it "cannot instantiate azure_client vault client without a vault name" do
vault_api_client = ::Azure::KeyVault::Profiles::Latest::Mgmt::Client
assert_raises(Train::UserError) do
connection.azure_client(vault_api_client)
end
end
end

describe "connect" do
it "validate credentials" do
connection.connect
token = credentials[:credentials].instance_variable_get(:@token_provider)
_(token.class).must_equal MsRestAzure::ApplicationTokenProvider

_(credentials[:credentials].class).must_equal MsRest::TokenCredentials
_(credentials[:tenant_id]).must_equal "test_tenant_id"
_(credentials[:client_id]).must_equal "test_client_id"
_(credentials[:client_secret]).must_equal "test_client_secret"
_(credentials[:subscription_id]).must_equal "test_subscription_id"
end

it "validate msi credentials" do
options[:client_id] = nil
options[:client_secret] = nil
Train::Transports::Azure::Connection.any_instance.stubs(:port_open?).returns(true)

connection.connect
token = credentials[:credentials].instance_variable_get(:@token_provider)
_(token.class).must_equal MsRestAzure::MSITokenProvider

_(credentials[:credentials].class).must_equal MsRest::TokenCredentials
_(credentials[:tenant_id]).must_equal "test_tenant_id"
_(credentials[:subscription_id]).must_equal "test_subscription_id"
_(credentials[:client_id]).must_be_nil
_(credentials[:client_secret]).must_be_nil
_(options[:msi_port]).must_equal 50342
end
end

describe "unique_identifier" do
Expand Down
5 changes: 0 additions & 5 deletions train.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,6 @@ Gem::Specification.new do |spec|
# azure, docker, gcp dependencies
spec.add_dependency "activesupport", ">= 6.0.3.1"
spec.add_dependency "inifile", "~> 3.0"
spec.add_dependency "azure_graph_rbac", "~> 0.16"
spec.add_dependency "azure_mgmt_key_vault", "~> 0.17"
spec.add_dependency "azure_mgmt_resources", "~> 0.15"
spec.add_dependency "azure_mgmt_security", "~> 0.18"
spec.add_dependency "azure_mgmt_storage", "~> 0.18"
spec.add_dependency "docker-api", ">= 1.26", "< 3.0"
spec.add_dependency "google-api-client", ">= 0.23.9", "<= 0.52.0"
spec.add_dependency "googleauth", ">= 0.6.6", "<= 0.14.0"
Expand Down