From b4b6fff17a63ea1275f5e14063f012c31507ba75 Mon Sep 17 00:00:00 2001 From: "Martin, Dereck" Date: Thu, 11 Mar 2021 21:24:11 -0500 Subject: [PATCH] Add guests and guest_members functionality for projects --- lib/puppet/provider/harbor_project/swagger.rb | 98 +++++++++++++++++-- lib/puppet/type/harbor_project.rb | 16 +++ spec/unit/puppet/type/harbor_project_spec.rb | 22 +++++ 3 files changed, 128 insertions(+), 8 deletions(-) diff --git a/lib/puppet/provider/harbor_project/swagger.rb b/lib/puppet/provider/harbor_project/swagger.rb index c29e612..8058b14 100644 --- a/lib/puppet/provider/harbor_project/swagger.rb +++ b/lib/puppet/provider/harbor_project/swagger.rb @@ -15,6 +15,8 @@ def self.instances auto_scan: project.metadata.auto_scan.nil? ? :false : project.metadata.auto_scan.to_sym, members: get_project_member_names(project.project_id), member_groups: get_project_member_group_names(project.project_id), + guests: get_project_guest_names(project.project_id), + guest_groups: get_project_guest_group_names(project.project_id), provider: :swagger, ) end @@ -48,21 +50,38 @@ def self.do_login PuppetX::Walkamongus::Harbor::Client.do_login end + def self.get_project_members_with_entity_type_and_role_id(project_id, entity_type, role_id) + api_instance = do_login + members_and_groups = api_instance[:legacy_client].projects_project_id_members_get(project_id) + with_entity_type = members_and_groups.select { |m| m.entity_type == entity_type } + with_role_id = with_entity_type.select { |m| m.role_id == role_id } + debug(with_role_id) + with_role_id + end + def self.get_project_member_names(project_id) - members = get_project_members_with_entity_type(project_id, 'u') + members = get_project_members_with_entity_type_and_role_id(project_id, 'u', 2) names = members.map { |m| m.entity_name } names.sort!.delete('admin') names end - def self.get_project_members_with_entity_type(project_id, type) - api_instance = do_login - members_and_groups = api_instance[:legacy_client].projects_project_id_members_get(project_id) - members_and_groups.select { |m| m.entity_type == type } + def self.get_project_member_group_names(project_id) + members = get_project_members_with_entity_type_and_role_id(project_id, 'g', 2) + names = members.map { |m| m.entity_name } + names.sort! + names end - def self.get_project_member_group_names(project_id) - members = get_project_members_with_entity_type(project_id, 'g') + def self.get_project_guest_names(project_id) + members = get_project_members_with_entity_type_and_role_id(project_id, 'u', 3) + names = members.map { |m| m.entity_name } + names.sort!.delete('admin') + names + end + + def self.get_project_guest_group_names(project_id) + members = get_project_members_with_entity_type_and_role_id(project_id, 'g', 3) names = members.map { |m| m.entity_name } names.sort! names @@ -137,7 +156,7 @@ def create rescue Harbor1Client::ApiError => e puts "Exception when calling ProductsApi->projects_post: #{e}" end - return nil if resource[:members].nil? and resource[:member_groups].nil? + return nil if resource[:members].nil? and resource[:member_groups].nil? and resource[:guests].nil? and resource[:guest_groups].nil? id = get_project_id_by_name(resource[:name]) unless resource[:members].nil? members = resource[:members] @@ -147,6 +166,14 @@ def create member_groups = resource[:member_groups] add_member_groups_to_project(id, member_groups) end + unless resource[:guests].nil? + guests = resource[:guests] + add_guests_to_project(id, guests) + end + unless resource[:guest_groups].nil? + guest_groups = resource[:guest_groups] + add_guest_groups_to_project(id, guest_groups) + end end def get_project_id_by_name(project_name) @@ -203,6 +230,21 @@ def members=(_value) add_members_to_project(id, members_to_add) unless members_to_add.empty? end + def guests + id = get_project_id_by_name(resource[:name]) + self.class.get_project_guest_names(id) + end + + def guests=(_value) + id = get_project_id_by_name(resource[:name]) + current_guests = self.class.get_project_guest_names(id) + guests = resource[:guests] + guests_to_delete = current_guests - guests + guests_to_add = guests - current_guests + remove_guests_from_project(id, guests_to_delete) unless guests_to_delete.empty? + add_guests_to_project(id, guests_to_add) unless guests_to_add.empty? + end + def remove_members_from_project(project_id, member_names) api_instance = self.class.do_login member_names.sort! @@ -212,6 +254,10 @@ def remove_members_from_project(project_id, member_names) end end + def remove_guests_from_project(project_id, guest_names) + remove_members_from_project(project_id, guest_names) + end + def get_project_member_id_by_name(project_id, name) api_instance = self.class.do_login opts = { @@ -229,6 +275,14 @@ def add_members_to_project(project_id, member_names) end end + def add_guests_to_project(project_id, guest_names) + guest_names.sort! + guest_names.each do |name| + opts = { project_member: { role_id: 3, member_user: { "username": name.to_s } } } # role_id 3 == 'Guest' + post_project_members(project_id, opts) + end + end + def post_project_members(project_id, opts) api_instance = self.class.do_login begin @@ -255,10 +309,29 @@ def member_groups=(_value) add_member_groups_to_project(project_id, member_groups_to_add) unless member_groups_to_add.empty? end + def guest_groups + id = get_project_id_by_name(resource[:name]) + self.class.get_project_guest_group_names(id) + end + + def guest_groups=(_value) + project_id = get_project_id_by_name(resource[:name]) + current_guest_groups = self.class.get_project_guest_group_names(project_id) + guest_groups = resource[:guest_groups] + guest_groups_to_delete = current_guest_groups - guest_groups + guest_groups_to_add = guest_groups - current_guest_groups + remove_guest_groups_from_project(project_id, guest_groups_to_delete) unless guest_groups_to_delete.empty? + add_guest_groups_to_project(project_id, guest_groups_to_add) unless guest_groups_to_add.empty? + end + def remove_member_groups_from_project(project_id, group_names) remove_members_from_project(project_id, group_names) end + def remove_guest_groups_from_project(project_id, group_names) + remove_members_from_project(project_id, group_names) + end + def add_member_groups_to_project(project_id, member_group_names) member_group_names.sort! member_group_names.each do |name| @@ -268,6 +341,15 @@ def add_member_groups_to_project(project_id, member_group_names) end end + def add_guest_groups_to_project(project_id, guest_group_names) + guest_group_names.sort! + guest_group_names.each do |name| + gid = get_usergroup_id_by_name(name) + opts = { project_member: { role_id: 3, member_group: { "id": gid } } } # role_id 3 == 'Guest' + post_project_members(project_id, opts) + end + end + def get_usergroup_id_by_name(name) api_instance = self.class.do_login all_groups = api_instance[:legacy_client].usergroups_get() diff --git a/lib/puppet/type/harbor_project.rb b/lib/puppet/type/harbor_project.rb index 5ef9d4a..ba4a3b3 100644 --- a/lib/puppet/type/harbor_project.rb +++ b/lib/puppet/type/harbor_project.rb @@ -10,6 +10,8 @@ public => 'true', members => ['bob', 'alice'], member_groups => ['This Team', 'That Team'], + guests => ['bob', 'alice'], + guest_groups => ['This Team', 'That Team'], } DESC @@ -44,4 +46,18 @@ def insync?(is) is.sort == should.sort end end + + newproperty(:guests, array_matching: :all) do + desc 'An array of guests for the project' + def insync?(is) + is.sort == should.sort + end + end + + newproperty(:guest_groups, array_matching: :all) do + desc 'An array of guest groups for the project' + def insync?(is) + is.sort == should.sort + end + end end diff --git a/spec/unit/puppet/type/harbor_project_spec.rb b/spec/unit/puppet/type/harbor_project_spec.rb index 02d9b95..49146db 100644 --- a/spec/unit/puppet/type/harbor_project_spec.rb +++ b/spec/unit/puppet/type/harbor_project_spec.rb @@ -114,6 +114,28 @@ end end end + + describe "guests" do + [ [], ['a_name'], ['a_name', 'another_name']].each do |value| + it "should support array of string values: #{value}" do + expect { described_class.new({ + :name => 'the_project', + :guests => value, + }) }.to_not raise_error + end + end + end + + describe "guest_groups" do + [ [], ['a_group'], ['a_group', 'another_group']].each do |value| + it "should support array of string values: #{value}" do + expect { described_class.new({ + :name => 'the_project', + :guest_groups => value, + }) }.to_not raise_error + end + end + end end end end