From 0027bf6893ce4e2643ae6c2bfc26825a48f01cce Mon Sep 17 00:00:00 2001 From: Takashi Kajinami Date: Sat, 28 Aug 2021 23:43:53 +0900 Subject: [PATCH] Support system/domain scope credential This change introduces the base implementation to use system scope credential or domain scope credential to request OpenStack API in each provider implementations. Change-Id: If3781cd2ed828126ef1388553f4b85eed78196e7 --- lib/puppet/provider/openstack/auth.rb | 6 +- lib/puppet/provider/openstack/credentials.rb | 37 +++++++++++- ...tem-scope-credential-113608525e12a22d.yaml | 6 ++ .../provider/openstack/credentials_spec.rb | 59 ++++++++++++++++++- 4 files changed, 101 insertions(+), 7 deletions(-) create mode 100644 releasenotes/notes/system-scope-credential-113608525e12a22d.yaml diff --git a/lib/puppet/provider/openstack/auth.rb b/lib/puppet/provider/openstack/auth.rb index 743071db..cee556f8 100644 --- a/lib/puppet/provider/openstack/auth.rb +++ b/lib/puppet/provider/openstack/auth.rb @@ -32,14 +32,14 @@ module Puppet::Provider::Openstack::Auth RCFILENAME end - def request(service, action, properties=nil, options={}) + def request(service, action, properties=nil, options={}, scope='project') properties ||= [] set_credentials(@credentials, get_os_vars_from_env) - unless @credentials.set? + unless @credentials.set? and (!@credentials.scope_set? or @credentials.scope == scope) @credentials.unset set_credentials(@credentials, get_os_vars_from_rcfile(rc_filename)) end - unless @credentials.set? + unless @credentials.set? and (!@credentials.scope_set? or @credentials.scope == scope) raise(Puppet::Error::OpenstackAuthInputError, 'Insufficient credentials to authenticate') end super(service, action, properties, @credentials, options) diff --git a/lib/puppet/provider/openstack/credentials.rb b/lib/puppet/provider/openstack/credentials.rb index 1fa852a1..5f65512b 100644 --- a/lib/puppet/provider/openstack/credentials.rb +++ b/lib/puppet/provider/openstack/credentials.rb @@ -40,6 +40,20 @@ class Puppet::Provider::Openstack::Credentials env end + def scope_set? + @project_name + end + + def scope + if @project_name + return 'project' + else + # When only service token is used, there is not way to determine + # the scope unless we inspect the token using keystone API call. + return nil + end + end + def user_password_set? return true if @username && @password && @project_name && @auth_url end @@ -70,6 +84,7 @@ class Puppet::Provider::Openstack::CredentialsV3 < Puppet::Provider::Openstack:: :project_domain_id, :project_domain_name, :project_id, + :system_scope, :trust_id, :user_domain_id, :user_domain_name, @@ -82,8 +97,28 @@ class Puppet::Provider::Openstack::CredentialsV3 < Puppet::Provider::Openstack:: KEYS.include?(name.to_sym) || super end + def user_set? + @username || @user_id + end + + def scope_set? + @system_scope || @domain_name || @domain_id || @project_name || @project_id + end + + def scope + if @project_name || @project_id + return 'project' + elsif @domain_name || @domain_id + return 'domain' + elsif @system_scope + return 'system' + else + return nil + end + end + def user_password_set? - return true if (@username || @user_id) && @password && (@project_name || @project_id) && @auth_url + return true if user_set? && @password && scope_set? && @auth_url end def initialize diff --git a/releasenotes/notes/system-scope-credential-113608525e12a22d.yaml b/releasenotes/notes/system-scope-credential-113608525e12a22d.yaml new file mode 100644 index 00000000..3a7ae40b --- /dev/null +++ b/releasenotes/notes/system-scope-credential-113608525e12a22d.yaml @@ -0,0 +1,6 @@ +--- +features: + - | + Now ``Puppet::Provider::Openstack::CredentialsV3`` supports system scope + credential and domain scope credential in addition to project scope + credential. diff --git a/spec/unit/provider/openstack/credentials_spec.rb b/spec/unit/provider/openstack/credentials_spec.rb index 3baa4eb4..9f06d41c 100644 --- a/spec/unit/provider/openstack/credentials_spec.rb +++ b/spec/unit/provider/openstack/credentials_spec.rb @@ -47,7 +47,7 @@ describe Puppet::Provider::Openstack::Credentials do describe '#password_set?' do context "with user credentials" do - it 'is successful' do + it 'is successful with project scope credential' do creds.auth_url = 'auth_url' creds.password = 'password' creds.project_name = 'project_name' @@ -56,6 +56,24 @@ describe Puppet::Provider::Openstack::Credentials do expect(creds.service_token_set?).to be_falsey end + it 'is successful with project scope credential' do + creds.auth_url = 'auth_url' + creds.password = 'password' + creds.domain_name = 'domain_name' + creds.username = 'username' + expect(creds.user_password_set?).to be_truthy + expect(creds.service_token_set?).to be_falsey + end + + it 'is successful with system scope credential' do + creds.auth_url = 'auth_url' + creds.password = 'password' + creds.system_scope = 'all' + creds.username = 'username' + expect(creds.user_password_set?).to be_truthy + expect(creds.service_token_set?).to be_falsey + end + it 'fails' do creds.auth_url = 'auth_url' creds.password = 'password' @@ -87,18 +105,22 @@ describe Puppet::Provider::Openstack::Credentials do creds.password = 'password' creds.project_name = 'project_name' creds.domain_name = 'domain_name' + creds.system_scope = 'system_scope' creds.username = 'username' creds.token = 'token' creds.endpoint = 'endpoint' + creds.region_name = 'region_name' creds.identity_api_version = 'identity_api_version' creds.unset expect(creds.auth_url).to eq('') expect(creds.password).to eq('') expect(creds.project_name).to eq('') expect(creds.domain_name).to eq('') + expect(creds.system_scope).to eq('') expect(creds.username).to eq('') expect(creds.token).to eq('') expect(creds.endpoint).to eq('') + expect(creds.region_name).to eq('') expect(creds.identity_api_version).to eq('identity_api_version') newcreds = Puppet::Provider::Openstack::CredentialsV3.new expect(newcreds.identity_api_version).to eq('3') @@ -112,20 +134,24 @@ describe Puppet::Provider::Openstack::Credentials do creds.auth_url = 'auth_url' creds.password = 'password' creds.project_name = 'project_name' + creds.domain_name = 'domain_name' + creds.system_scope = 'all' creds.username = 'username' creds.token = 'token' creds.endpoint = 'endpoint' - creds.identity_api_version = 'identity_api_version' creds.region_name = 'Region1' + creds.identity_api_version = 'identity_api_version' expect(creds.to_env).to eq({ 'OS_USERNAME' => 'username', 'OS_PASSWORD' => 'password', 'OS_PROJECT_NAME' => 'project_name', + 'OS_DOMAIN_NAME' => 'domain_name', + 'OS_SYSTEM_SCOPE' => 'all', 'OS_AUTH_URL' => 'auth_url', 'OS_TOKEN' => 'token', 'OS_ENDPOINT' => 'endpoint', - 'OS_IDENTITY_API_VERSION' => 'identity_api_version', 'OS_REGION_NAME' => 'Region1', + 'OS_IDENTITY_API_VERSION' => 'identity_api_version', }) end end @@ -149,6 +175,24 @@ describe Puppet::Provider::Openstack::Credentials do expect(creds.user_password_set?).to be_truthy end end + describe '#password_set? with username and domain_name' do + it 'is successful' do + creds.auth_url = 'auth_url' + creds.password = 'password' + creds.domain_name = 'domain_name' + creds.username = 'username' + expect(creds.user_password_set?).to be_truthy + end + end + describe '#password_set? with username and system_scope' do + it 'is successful' do + creds.auth_url = 'auth_url' + creds.password = 'password' + creds.system_scope = 'all' + creds.username = 'username' + expect(creds.user_password_set?).to be_truthy + end + end describe '#password_set? with user_id and project_id' do it 'is successful' do creds.auth_url = 'auth_url' @@ -158,5 +202,14 @@ describe Puppet::Provider::Openstack::Credentials do expect(creds.user_password_set?).to be_truthy end end + describe '#password_set? with user_id and domain_id' do + it 'is successful' do + creds.auth_url = 'auth_url' + creds.password = 'password' + creds.domain_id = 'domid' + creds.user_id = 'userid' + expect(creds.user_password_set?).to be_truthy + end + end end end