-
Notifications
You must be signed in to change notification settings - Fork 27
Add additional types and providers #24
base: master
Are you sure you want to change the base?
Conversation
Thank you for your contribution @jonasdemoor . I will check the changes once I have a chance, that's a pretty big PR to check! |
require 'puppet/resource_api/simple_provider' | ||
require 'puppet_x/minio/client' | ||
|
||
DEFAUlT_TARGET_ALIAS ||= 'puppet'.freeze |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest removing the hardcoded alias and adding it as a parameter here and in other types you're adding. I'm sure it would work as it is for certain use-cases, but it's always better to be flexible and allow module consumers to decide what alias they want to use.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is bit of a chicken-egg problem unfortunately, as we need an alias to query MinIO for state.
I was thinking about managing a small JSON file (e.g. /usr/local/etc/minio_state.json
) that would hold the currently selected alias by the user. We can manage this from the manifests or we can write a small provider for that, for example.
I was also thinking about using this file for saving user passwords to from the minio_user
provider, then we could update a user's password without having to (manually) delete said user.
Does this sound okay for you? Just thinking out loud here :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I solved this by setting /root/.minio_default_alias
in the manifests and retrieving the contents of that file in the providers (via the alias method in puppet_x/minio/client
desc: 'The name of the resource you want to manage.', | ||
behaviour: :namevar, | ||
}, | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add autorequire here and in other new types, as I did in aliases:
autorequire: {
file: '/root/.minioclient',
}
Otherwise, puppet sometimes tries to create resources before minio client is set and that fails for obvious reasons:
Error: minio_bucket[testbucket]: Creating: Failed after 0.000269 seconds: Symlink to minio client does not exist at /root/.minioclient. Make sure you installed the client before managing minio resources.
Error: /Stage[main]/Main/Minio_bucket[testbucket]: Could not evaluate: Execution encountered an error
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I forgot those indeed, I will add them to the types.
desc: 'Whether this resource should be present or absent on the target system.', | ||
default: 'present', | ||
}, | ||
name: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If that's possible, please also add parameters for region and locking.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added some additional parameters for region and locking
operations << "admin group add #{DEFAUlT_TARGET_ALIAS} #{name} #{should[:members].join(' ')}" | ||
|
||
operations << "admin group disable #{DEFAUlT_TARGET_ALIAS} #{name}" unless should[:enabled] | ||
operations << "admin policy set #{DEFAUlT_TARGET_ALIAS} #{should[:policies].join(',')} group=#{name}" unless should[:policies].nil? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest moving the policy assignment to a dedicated type that would only assign an existing policy to a user or to a group.
In my experience, as soon as a type started doing more than one thing, module consumers start having problems using the module. So it's better to give consumers smaller simple building blocks and let them decide how they want to combine those. Of course given the client supports a dedicated command for assignment (in the case of minio, policies have the dedicated command, but groups do not).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes more sense indeed, and would simplify the user and group providers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Policy assignment is now done with a dedicated minio_policy_assignment
provider. Since there's no real API endpoint for retrieving policy assignments, the get
method returns resources with <subject_type>_<subject>
as composite namevar. So it's only possible to update those resources.
lib/puppet/type/minio_user.rb
Outdated
behaviour: :namevar, | ||
}, | ||
secret_key: { | ||
type: 'Variant[Sensitive[String], String]', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you please add length restrictions to the string types? The secret key should be between 8 and 40 characters in length.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added some length restrictions like you described.
lib/puppet/type/minio_user.rb
Outdated
}, | ||
access_key: { | ||
type: 'String', | ||
desc: 'The API access key', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a mention that it's also a username.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I modified the description a bit
|
||
f = Tempfile.new(["#{name}-policy", '.json']) | ||
begin | ||
json_policy = Hash[:Version => DEFAULT_POLICY_VERSION, :Statement => should[:statement]].to_json |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- You could just do
{:Version => ...}
with curly brackets withoutHash
- you don't really need
f.rewind
. For further closing and deleting the file, it's not important where the internal cursor for the file is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- I adjusted the Hash syntax to the one you described
- When I didn't rewind the file,
mcli
couldn't read the JSON file with the policy object, because the CLI read an empty string. After some searching, I found that I had to rewind the file for it to work.
lib/puppet/type/minio_user.rb
Outdated
type: 'Optional[Array[String]]', | ||
desc: 'List of MinIO PBAC policies to set for this user.', | ||
}, | ||
member_of: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Do you really need it? I'd just remove it unless sure why would we need it.
- Could you please also add
enabled
parameter here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- This isn't really needed indeed, it's mostly cosmetic, so I removed it
- I added an additional
enabled
parameter
lib/puppet/type/minio_policy.rb
Outdated
version: { | ||
type: 'String', | ||
desc: 'Specifies the language syntax rules that are to be used to process a policy.', | ||
behaviour: :read_only, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why don't you just add a default value here instead of making it read only? In such a case, consumers could continue using the module when the version ever changes without making changes to the module code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a default value for the version
@jonasdemoor thank you again for your PR. I finally had time to look at it. I understand that some of my requests gonna require a lot of time to implement, so I suggest you fix whatever you have time for and let me know, so I take over and finish the remaining stuff myself. |
Hello @ZloeSabo , My apologies for taking so long to respond. Thank you very much for your detailed feedback, I'm reworking this PR based on your feedback. |
Instead of hardcoding the alias.
This has been moved to a dedicated minio_policy_assignment provider.
Moved to minio_policy_assignment.
Instead of setting a global variable in the constructor. Otherwise, catalog compilation fails at the first resource.
Hi @ZloeSabo, I reworked the providers and types based on your feedback. Feel free to let me know if there's anything else that could be improved or handled differently :) |
I'm still working on the unit tests, so CI may still fail |
This PR adds the following types and providers for managing local MinIO resources:
minio_user
minio_group
minio_bucket
minio_policy
These work for the most part; there are still some caveats:
minio_user
orminio_group
. Attempting to mix those two providers for policy assignment might result in assigned policies being overwritten.minio_group
provider processes updates by recreating the whole group to keeps things simple. A proper update would require removing and/or adding members via the CLI in a certain order.puppet
is hardcoded into the provider code, since the MinIO CLI needs an alias to retrieve and create MinIO resources. This alias would need to be created before running the providers.I'm running the providers on a Debian 11 VM against the following MinIO versions:
I'm still working on my Ruby skills, feedback is always welcome :)