File: openstack.rb

package info (click to toggle)
puppet-module-keystone 25.0.0-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,428 kB
  • sloc: ruby: 9,684; pascal: 295; python: 38; makefile: 10; sh: 10
file content (167 lines) | stat: -rw-r--r-- 4,945 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
require File.join(File.dirname(__FILE__), '..','..','..', 'puppet/provider/keystone')

Puppet::Type.type(:keystone_user).provide(
  :openstack,
  :parent => Puppet::Provider::Keystone
) do

  desc "Provider to manage keystone users."

  @credentials = Puppet::Provider::Openstack::CredentialsV3.new

  include PuppetX::Keystone::CompositeNamevar::Helpers

  def initialize(value={})
    super(value)
    @property_flush = {}
  end

  def self.do_not_manage
    @do_not_manage
  end

  def self.do_not_manage=(value)
    @do_not_manage = value
  end

  def create
    if self.class.do_not_manage
      fail("Not managing Keystone_user[#{@resource[:name]}] due to earlier Keystone API failures.")
    end
    properties = [resource[:name]]
    if resource[:enabled] == :true
      properties << '--enable'
    elsif resource[:enabled] == :false
      properties << '--disable'
    end
    if resource[:password]
      properties << '--password' << resource[:password]
    end
    if resource[:description]
      properties << '--description' << resource[:description]
    end
    if resource[:email]
      properties << '--email' << resource[:email]
    end
    properties << '--domain' << resource[:domain]
    @property_hash = self.class.system_request('user', 'create', properties)
    @property_hash[:name] = resource[:name]
    @property_hash[:domain] = resource[:domain]
    @property_hash[:ensure] = :present
  end

  def destroy
    self.class.system_request('user', 'delete', id)
    @property_hash.clear
  end

  def flush
    options = []
    if @property_flush && !@property_flush.empty?
      options << '--enable'  if @property_flush[:enabled] == :true
      options << '--disable' if @property_flush[:enabled] == :false
      # There is a --description flag for the set command, but it does not work if the value is empty
      options << '--password' << resource[:password] if @property_flush[:password]
      options << '--description' << resource[:description] if @property_flush[:description]
      options << '--email'    << resource[:email]    if @property_flush[:email]
      # project handled in tenant= separately
      unless options.empty?
        options << id
        self.class.system_request('user', 'set', options)
      end
      @property_flush.clear
    end
  end

  mk_resource_methods

  def exists?
    return true if @property_hash[:ensure] == :present
    domain_name = self.class.domain_id_from_name(resource[:domain])
    @property_hash =
      self.class.fetch_user(resource[:name], domain_name)
    @property_hash ||= {}
    # This can happen in bad LDAP mapping
    @property_hash[:enabled] = 'true' if @property_hash[:enabled].nil?
    @property_hash[:domain] = domain_name

    return false if @property_hash.nil? || @property_hash[:id].nil?
    true
  end

  # Types properties
  def enabled
    is_enabled = @property_hash[:enabled].downcase.chomp == 'true' ? true : false
    bool_to_sym(is_enabled)
  end

  def enabled=(value)
    @property_flush[:enabled] = value
  end

  def description=(value)
    @property_flush[:description] = value
  end

  def email=(value)
    @property_flush[:email] = value
  end

  def password
    passwd = nil
    return passwd if resource[:password] == nil
    if resource[:enabled] == :false || resource[:replace_password] == :false
      # Unchanged password
      passwd = resource[:password]
    else
      # Password validation
      credentials = Puppet::Provider::Openstack::CredentialsV3.new
      unless credentials.auth_url = self.class.get_auth_url
        raise(Puppet::Error::OpenstackAuthInputError, "Could not find authentication url to validate user's password.")
      end
      credentials.password = resource[:password]
      credentials.user_id = id

      # NOTE: The only reason we use username is so that the openstack provider
      # will know we are doing v3password auth - otherwise, it is not used.  The
      # user_id uniquely identifies the user including domain.
      credentials.username = resource[:name]

      begin
        token = Puppet::Provider::Openstack.request('token', 'issue', ['--format', 'value'], credentials)
      rescue Puppet::Error::OpenstackUnauthorizedError
        # password is invalid
      else
        passwd = resource[:password] unless token.empty?
      end
    end
    return passwd
  end

  def password=(value)
    if self.class.do_not_manage
      fail("Not managing Keystone_user[#{@resource[:name]}] due to earlier Keystone API failures.")
    end
    @property_flush[:password] = value
  end

  def replace_password
    @property_hash[:replace_password]
  end

  def replace_password=(value)
    if self.class.do_not_manage
      fail("Not managing Keystone_user[#{@resource[:name]}] due to earlier Keystone API failures.")
    end
    @property_flush[:replace_password] = value
  end

  def domain
    @property_hash[:domain]
  end

  def domain_id
    @property_hash[:domain_id]
  end

end