1 require 'puppet/util/inifile'
2 require 'puppet/provider/openstack'
3 require 'puppet/provider/openstack/auth'
4 require 'puppet/provider/openstack/credentials'
5 require 'puppet/provider/keystone/util'
7 class Puppet::Provider::Keystone < Puppet::Provider::Openstack
9 extend Puppet::Provider::Openstack::Auth
11 INI_FILENAME = '/etc/keystone/keystone.conf'
16 endpoint = ENV['OS_AUTH_URL']
18 endpoint = get_os_vars_from_rcfile(rc_filename)['OS_AUTH_URL']
20 # This is from legacy but seems wrong, we want auth_url not url!
21 endpoint = get_admin_endpoint
25 raise(Puppet::Error::OpenstackAuthInputError, 'Could not find auth url to check user password.')
30 def self.admin_endpoint
31 @admin_endpoint ||= get_admin_endpoint
34 # use the domain in this order:
35 # 1 - the domain name specified in the resource definition - resource[:domain]
36 # 2 - the domain name part of the resource name/title e.g. user_name::user_domain
37 # if passed in by name_and_domain above
38 # 3 - use the specified default_domain_name
39 # 4 - lookup the default domain
40 # 5 - use 'Default' - the "default" default domain if no other one is configured
41 # Usage: name_and_domain(resource[:name], resource[:domain], default_domain_name)
42 def self.name_and_domain(namedomstr, domain_from_resource=nil, default_domain_name=nil)
43 name, domain = Util.split_domain(namedomstr)
45 if domain_from_resource
46 ret << domain_from_resource
49 elsif default_domain_name
50 ret << default_domain_name
60 @admin_token ||= get_admin_token
63 def self.get_admin_token
64 if keystone_file and keystone_file['DEFAULT'] and keystone_file['DEFAULT']['admin_token']
65 return "#{keystone_file['DEFAULT']['admin_token'].strip}"
71 def self.get_admin_endpoint
73 if keystone_file['DEFAULT']
74 if keystone_file['DEFAULT']['admin_endpoint']
75 auth_url = keystone_file['DEFAULT']['admin_endpoint'].strip.chomp('/')
76 return "#{auth_url}/v#{@credentials.version}/"
79 if keystone_file['DEFAULT']['admin_port']
80 admin_port = keystone_file['DEFAULT']['admin_port'].strip
85 if keystone_file['DEFAULT']['admin_bind_host']
86 host = keystone_file['DEFAULT']['admin_bind_host'].strip
97 if keystone_file['ssl'] && keystone_file['ssl']['enable'] && keystone_file['ssl']['enable'].strip.downcase == 'true'
104 "#{protocol}://#{host}:#{admin_port}/v#{@credentials.version}/"
107 def self.request(service, action, properties=nil)
109 rescue Puppet::Error::OpenstackAuthInputError => error
110 request_by_service_token(service, action, error, properties)
113 def self.request_by_service_token(service, action, error, properties=nil)
115 @credentials.token = get_admin_token
116 @credentials.url = get_admin_endpoint
117 raise error unless @credentials.service_token_set?
118 Puppet::Provider::Openstack.request(service, action, properties, @credentials)
121 def self.ini_filename
125 def self.default_domain
126 domain_hash[default_domain_id]
130 return @domain_hash if @domain_hash
131 list = request('domain', 'list')
132 @domain_hash = Hash[list.collect{|domain| [domain[:id], domain[:name]]}]
136 def self.domain_name_from_id(id)
140 def self.default_domain_id
141 return @default_domain_id if @default_domain_id
142 if keystone_file and keystone_file['identity'] and keystone_file['identity']['default_domain_id']
143 @default_domain_id = "#{keystone_file['identity']['default_domain_id'].strip}"
145 @default_domain_id = 'default'
150 def self.keystone_file
151 return @keystone_file if @keystone_file
152 if File.exists?(ini_filename)
153 @keystone_file = Puppet::Util::IniConfig::File.new
154 @keystone_file.read(ini_filename)
159 # Helper functions to use on the pre-validated enabled field
160 def bool_to_sym(bool)
161 bool == true ? :true : :false
165 sym == :true ? true : false