Skip to content
This repository has been archived by the owner on Dec 1, 2023. It is now read-only.

Add additional types and providers #24

Open
wants to merge 19 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
a92b395
providers/minio_client_alias: Move to unwrap_maybe_sensitive to utils
jonasdemoor Nov 26, 2021
065eb38
Add minio_bucket provider
jonasdemoor Nov 9, 2021
4f65e40
Add minio_user provider
jonasdemoor Nov 9, 2021
c497a9c
Add minio_group provider
jonasdemoor Nov 10, 2021
31a6abb
Add minio_policy provider
jonasdemoor Nov 17, 2021
bb4395e
manifests: Add parameter for setting a default client alias
jonasdemoor Apr 5, 2022
b6e4b05
lib/puppet_x/minio/client: Add helper method for using default alias
jonasdemoor Apr 5, 2022
7709e88
providers: Use helper alias method from client
jonasdemoor Apr 5, 2022
4694bab
Add minio_policy_assignment provider
jonasdemoor Apr 7, 2022
bce3f3e
lib/puppet/minio_user: Remove policy assignment
jonasdemoor Apr 5, 2022
869cdd8
lib/puppet/type/minio_group: Remove policy assignment
jonasdemoor Apr 7, 2022
44d0f7e
lib/puppet/type/minio_user: Add secret key length restrictions
jonasdemoor Apr 5, 2022
1b08458
lib/puppet/type/minio_user: Clarify parameter descriptions
jonasdemoor Apr 5, 2022
0fdb959
lib/puppet/minio_user: Add enabled param
jonasdemoor Apr 7, 2022
0311ba8
lib/puppet/provider/minio_policy: Also sanitize non-symbolizes keys
jonasdemoor Apr 7, 2022
a79bedc
lib/puppet/minio_policy: Use default for version parameter
jonasdemoor Apr 7, 2022
21526e8
lib/puppet/minio_bucket: Add region and object lock params
jonasdemoor Apr 6, 2022
3bb8830
lib/puppet/minio_bucket: Add insync? method
jonasdemoor Apr 7, 2022
bf9a2ad
providers: Use client alias method directly for retrieving alias
jonasdemoor Apr 12, 2022
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
71 changes: 71 additions & 0 deletions lib/puppet/provider/minio_bucket/minio_bucket.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# frozen_string_literal: true

require 'puppet/resource_api/simple_provider'
require 'puppet_x/minio/client'

# Implementation for the minio_bucket type using the Resource API.
class Puppet::Provider::MinioBucket::MinioBucket < Puppet::ResourceApi::SimpleProvider
def get(context)
context.debug('Returning list of minio buckets')
return [] unless PuppetX::Minio::Client.installed? || PuppetX::Minio::Client.alias_set?

@instances = []
PuppetX::Minio::Client.execute("ls #{PuppetX::Minio::Client.alias}").each do |json_bucket|
name = json_bucket['key'].chomp('/')
# `mcli stat` returns an array
data = PuppetX::Minio::Client.execute("stat #{PuppetX::Minio::Client.alias}/#{name}").first

@instances << to_puppet_bucket(data)
end
@instances
end

def create(context, name, should)
context.notice("Creating '#{name}' with #{should.inspect}")

flags = []
flags << "--region=#{should[:region]}" if should[:region]
flags << '--with-lock' if should[:enable_object_lock]

PuppetX::Minio::Client.execute("mb #{flags.join(' ')} #{PuppetX::Minio::Client.alias}/#{name}")
end

def update(context, name, should)
context.notice("Updating '#{name}' with #{should.inspect}")

operations = []
operations << "retention clear #{PuppetX::Minio::Client.alias}/#{name}" unless should[:enable_object_lock]

operations.each do |op|
PuppetX::Minio::Client.execute(op)
end
end

def delete(context, name)
context.notice("Deleting '#{name}'")
PuppetX::Minio::Client.execute("rb --force #{PuppetX::Minio::Client.alias}/#{name}")
end

def to_puppet_bucket(json)
name = json['url'].delete_prefix("#{PuppetX::Minio::Client.alias}/")
region = json['metadata']['location']
enable_object_lock = ! json['metadata']['ObjectLock']['enabled'].empty?

{
ensure: 'present',
name: name,
region: region,
enable_object_lock: enable_object_lock,
}
end

def insync?(context, _name, property_name, is_hash, should_hash)
context.debug("Checking whether #{property_name} is out of sync")
case property_name
when :region
# It's not possible to move a bucket to a different region
# after creation.
true
end
end
end
11 changes: 3 additions & 8 deletions lib/puppet/provider/minio_client_alias/minio_client_alias.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
require 'json'
require 'puppet/resource_api/simple_provider'
require 'puppet_x/minio/client'
require 'puppet_x/minio/util'

LEGACY_PATH_SUPPORT_MAP ||= {
'': 'auto',
Expand All @@ -12,6 +13,8 @@

# Implementation for the minio_client_alias type using the Resource API.
class Puppet::Provider::MinioClientAlias::MinioClientAlias < Puppet::ResourceApi::SimpleProvider
include PuppetX::Minio::Util

def get(context)
context.debug('Returning list of minio client aliases')
return [] unless PuppetX::Minio::Client.installed?
Expand Down Expand Up @@ -80,12 +83,4 @@ def to_puppet_alias(json)
path_lookup_support: path_lookup_support,
}
end

def unwrap_maybe_sensitive(param)
if param.is_a?(Puppet::Pops::Types::PSensitiveType::Sensitive)
return param.unwrap
end

param
end
end
74 changes: 74 additions & 0 deletions lib/puppet/provider/minio_group/minio_group.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# frozen_string_literal: true

require 'puppet/resource_api/simple_provider'
require 'puppet_x/minio/client'

GROUP_STATUS_MAP ||= {
'enabled': true,
'disabled': false,
}.freeze

# Implementation for the minio_group type using the Resource API.
class Puppet::Provider::MinioGroup::MinioGroup < Puppet::ResourceApi::SimpleProvider
def get(context)
context.debug('Returning list of minio groups')
return [] unless PuppetX::Minio::Client.installed? || PuppetX::Minio::Client.alias_set?

# `mcli admin group list` returns an array
json_groups = PuppetX::Minio::Client.execute("admin group list #{PuppetX::Minio::Client.alias}").first
return [] unless json_groups.key?('groups')

@instances = []
json_groups['groups'].each do |group|
# `mcli admin group info` returns an array
json_group_info = PuppetX::Minio::Client.execute("admin group info #{PuppetX::Minio::Client.alias} #{group}").first
@instances << to_puppet_group(json_group_info)
end
@instances
end

def create(context, name, should)
context.notice("Creating '#{name}' with #{should.inspect}")

operations = []
operations << "admin group add #{PuppetX::Minio::Client.alias} #{name} #{should[:members].join(' ')}"
operations << "admin group disable #{PuppetX::Minio::Client.alias} #{name}" unless should[:enabled]

operations.each do |op|
PuppetX::Minio::Client.execute(op)
end
end

def update(context, name, should)
context.notice("Updating '#{name}' with #{should.inspect}")

# TODO: Do a proper update instead of recreating the group
delete(context, name)
create(context, name, should)
end

def delete(context, name)
context.notice("Deleting '#{name}'")

members = PuppetX::Minio::Client.execute("admin group info #{PuppetX::Minio::Client.alias} #{name}").first['members']
operations = []

operations << "admin group remove #{PuppetX::Minio::Client.alias} #{name} #{members.join(' ')}"
operations << "admin group remove #{PuppetX::Minio::Client.alias} #{name}"

operations.each do |op|
PuppetX::Minio::Client.execute(op)
end
end

def to_puppet_group(json)
policies = if json['groupPolicy'].nil? then nil else json['groupPolicy'].split(',') end

{
ensure: 'present',
name: json['groupName'],
members: json['members'] || [],
enabled: GROUP_STATUS_MAP[json['groupStatus'].to_sym],
}
end
end
91 changes: 91 additions & 0 deletions lib/puppet/provider/minio_policy/minio_policy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# frozen_string_literal: true

require 'json'
require 'tempfile'

require 'puppet/resource_api/simple_provider'
require 'puppet_x/minio/client'

# Implementation for the minio_policy type using the Resource API.
class Puppet::Provider::MinioPolicy::MinioPolicy < Puppet::ResourceApi::SimpleProvider
def get(context)
context.debug('Returning list of minio policies')
return [] unless PuppetX::Minio::Client.installed? || PuppetX::Minio::Client.alias_set?

json_policies = PuppetX::Minio::Client.execute("admin policy list #{PuppetX::Minio::Client.alias}")
return [] if json_policies.empty?

@instances = []
json_policies.each do |policy|
# `mcli admin policy info` returns an array
json_policy_info = PuppetX::Minio::Client.execute("admin policy info #{PuppetX::Minio::Client.alias} #{policy['policy']}").first
@instances << to_puppet_policy(json_policy_info)
end
@instances
end

def create(context, name, should)
context.notice("Creating '#{name}' with #{should.inspect}")

f = Tempfile.new(["#{name}-policy", '.json'])
begin
json_policy = {:Version => should[:version], :Statement => should[:statement]}.to_json

f.write(json_policy)
f.rewind

PuppetX::Minio::Client.execute("admin policy add #{PuppetX::Minio::Client.alias} #{name} #{f.path}")
ensure
f.close
f.unlink
end
end

def update(context, name, should)
context.notice("Updating '#{name}' with #{should.inspect}")

# There's currently no way to update an existing policy via the client,
# so delete and recreate the policy
delete(context, name)
create(context, name, should)
end

def delete(context, name)
context.notice("Deleting '#{name}'")
PuppetX::Minio::Client.execute("admin policy remove #{PuppetX::Minio::Client.alias} #{name}")
end

def to_puppet_policy(json)
statements = []
json['policyJSON']['Statement'].each do |s|
statements << sanitize_statement(s)
end

{
ensure: 'present',
name: json['policy'],
version: json['policyJSON']['Version'],
statement: statements,
}
end

def sanitize_statement(statement)
statement.transform_keys!(&:capitalize)

['Action', 'Resource', :Action, :Resource].each do |k|
statement[k].sort! unless statement[k].nil?
end

statement
end

def canonicalize(_context, resources)
resources.each do |r|
unless r[:statement].nil?
r[:statement].each do |s|
s = sanitize_statement(s)
end
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# frozen_string_literal: true

require 'puppet/resource_api/simple_provider'
require 'puppet_x/minio/client'

# Implementation for the minio_policy_assignment type using the Resource API.
class Puppet::Provider::MinioPolicyAssignment::MinioPolicyAssignment < Puppet::ResourceApi::SimpleProvider
def get(context)
context.debug('Returning list of minio policy assignments')
return [] unless PuppetX::Minio::Client.installed? || PuppetX::Minio::Client.alias_set?

@instances = []
PuppetX::Minio::Client.execute("admin user list #{PuppetX::Minio::Client.alias}").each do |json_user|
# `mcli admin user info` returns an array
json_user_info = PuppetX::Minio::Client.execute("admin user info #{PuppetX::Minio::Client.alias} #{json_user['accessKey']}").first
@instances << to_puppet_policy_assignment(json_user_info, 'user')
end

# `mcli admin group list` returns an array
json_groups = PuppetX::Minio::Client.execute("admin group list #{PuppetX::Minio::Client.alias}").first
json_groups.fetch('groups', []).each do |group|
# `mcli admin group info` returns an array
json_group_info = PuppetX::Minio::Client.execute("admin group info #{PuppetX::Minio::Client.alias} #{group}").first
@instances << to_puppet_policy_assignment(json_group_info, 'group')
end

@instances
end

def update(context, name, should)
context.notice("Updating '#{name}' with #{should.inspect}")
PuppetX::Minio::Client.execute("admin policy set #{PuppetX::Minio::Client.alias} #{should[:policies].join(',')} #{should[:subject_type]}=#{should[:subject]}")
end

def create(context, name, should)
context.warning('`create` method not implemented for `minio_policy_assignment` provider.')
end

def delete(context, name)
context.warning('`delete` method not implemented for `minio_policy_assignment` provider.')
end

def to_puppet_policy_assignment(json, subject_type)
case subject_type
when 'user'
subject = json.fetch('accessKey')
policies = json.fetch('policyName', '').split(',')
when 'group'
subject = json.fetch('groupName')
policies = json.fetch('groupPolicy', '').split(',')
else
raise Puppet::ExecutionFailure, "Unknown subject_type `#{subject_type}`. Supported values: user, group"
end

{
ensure: 'present',
title: "#{subject_type}_#{subject}",
subject: subject,
subject_type: subject_type,
policies: policies,
}
end
end
Loading