| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent d509da6 commit 6d31649
7 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -48,6 +48,7 @@ API examples | |||
| 48 | 48 | gl_objects/projects | |
| 49 | 49 | gl_objects/project_access_tokens | |
| 50 | 50 | gl_objects/protected_branches | |
| 51 | + gl_objects/protected_container_repositories | ||
| 51 | 52 | gl_objects/protected_environments | |
| 52 | 53 | gl_objects/protected_packages | |
| 53 | 54 | gl_objects/releases | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,44 @@ | |||
| 1 | + ################################ | ||
| 2 | + Protected container repositories | ||
| 3 | + ################################ | ||
| 4 | + | ||
| 5 | + You can list and manage container registry protection rules in a project. | ||
| 6 | + | ||
| 7 | + References | ||
| 8 | + ---------- | ||
| 9 | + | ||
| 10 | + * v4 API: | ||
| 11 | + | ||
| 12 | + + :class:`gitlab.v4.objects.ProjectRegistryProtectionRuleRule` | ||
| 13 | + + :class:`gitlab.v4.objects.ProjectRegistryProtectionRuleRuleManager` | ||
| 14 | + + :attr:`gitlab.v4.objects.Project.registry_protection_rules` | ||
| 15 | + | ||
| 16 | + * GitLab API: https://docs.gitlab.com/ee/api/project_container_registry_protection_rules.html | ||
| 17 | + | ||
| 18 | + Examples | ||
| 19 | + -------- | ||
| 20 | + | ||
| 21 | + List the container registry protection rules for a project:: | ||
| 22 | + | ||
| 23 | + registry_rules = project.registry_protection_rules.list() | ||
| 24 | + | ||
| 25 | + Create a container registry protection rule:: | ||
| 26 | + | ||
| 27 | + registry_rule = project.registry_protection_rules.create( | ||
| 28 | + { | ||
| 29 | + 'repository_path_pattern': 'test/image', | ||
| 30 | + 'minimum_access_level_for_push': 'maintainer', | ||
| 31 | + 'minimum_access_level_for_delete': 'maintainer', | ||
| 32 | + } | ||
| 33 | + ) | ||
| 34 | + | ||
| 35 | + Update a container registry protection rule:: | ||
| 36 | + | ||
| 37 | + registry_rule.minimum_access_level_for_push = 'owner' | ||
| 38 | + registry_rule.save() | ||
| 39 | + | ||
| 40 | + Delete a container registry protection rule:: | ||
| 41 | + | ||
| 42 | + registry_rule = project.registry_protection_rules.delete(registry_rule.id) | ||
| 43 | + # or | ||
| 44 | + registry_rule.delete() | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -54,6 +54,7 @@ | |||
| 54 | 54 | from .project_access_tokens import * | |
| 55 | 55 | from .projects import * | |
| 56 | 56 | from .push_rules import * | |
| 57 | + from .registry_protection_rules import * | ||
| 57 | 58 | from .releases import * | |
| 58 | 59 | from .repositories import * | |
| 59 | 60 | from .resource_groups import * | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -85,6 +85,9 @@ | |||
| 85 | 85 | ) | |
| 86 | 86 | from .project_access_tokens import ProjectAccessTokenManager # noqa: F401 | |
| 87 | 87 | from .push_rules import ProjectPushRulesManager # noqa: F401 | |
| 88 | + from .registry_protection_rules import ( # noqa: F401 | ||
| 89 | + ProjectRegistryProtectionRuleManager, | ||
| 90 | + ) | ||
| 88 | 91 | from .releases import ProjectReleaseManager # noqa: F401 | |
| 89 | 92 | from .repositories import RepositoryMixin | |
| 90 | 93 | from .resource_groups import ProjectResourceGroupManager | |
@@ -218,6 +221,7 @@ class Project( | |||
| 218 | 221 | protectedbranches: ProjectProtectedBranchManager | |
| 219 | 222 | protectedtags: ProjectProtectedTagManager | |
| 220 | 223 | pushrules: ProjectPushRulesManager | |
| 224 | + registry_protection_rules: ProjectRegistryProtectionRuleManager | ||
| 221 | 225 | releases: ProjectReleaseManager | |
| 222 | 226 | resource_groups: ProjectResourceGroupManager | |
| 223 | 227 | remote_mirrors: "ProjectRemoteMirrorManager" | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,35 @@ | |||
| 1 | + from gitlab.base import RESTManager, RESTObject | ||
| 2 | + from gitlab.mixins import CreateMixin, ListMixin, SaveMixin, UpdateMethod, UpdateMixin | ||
| 3 | + from gitlab.types import RequiredOptional | ||
| 4 | + | ||
| 5 | + __all__ = [ | ||
| 6 | + "ProjectRegistryProtectionRule", | ||
| 7 | + "ProjectRegistryProtectionRuleManager", | ||
| 8 | + ] | ||
| 9 | + | ||
| 10 | + | ||
| 11 | + class ProjectRegistryProtectionRule(SaveMixin, RESTObject): | ||
| 12 | + _repr_attr = "repository_path_pattern" | ||
| 13 | + | ||
| 14 | + | ||
| 15 | + class ProjectRegistryProtectionRuleManager( | ||
| 16 | + ListMixin, CreateMixin, UpdateMixin, RESTManager | ||
| 17 | + ): | ||
| 18 | + _path = "/projects/{project_id}/registry/protection/rules" | ||
| 19 | + _obj_cls = ProjectRegistryProtectionRule | ||
| 20 | + _from_parent_attrs = {"project_id": "id"} | ||
| 21 | + _create_attrs = RequiredOptional( | ||
| 22 | + required=("repository_path_pattern",), | ||
| 23 | + optional=( | ||
| 24 | + "minimum_access_level_for_push", | ||
| 25 | + "minimum_access_level_for_delete", | ||
| 26 | + ), | ||
| 27 | + ) | ||
| 28 | + _update_attrs = RequiredOptional( | ||
| 29 | + optional=( | ||
| 30 | + "repository_path_pattern", | ||
| 31 | + "minimum_access_level_for_push", | ||
| 32 | + "minimum_access_level_for_delete", | ||
| 33 | + ), | ||
| 34 | + ) | ||
| 35 | + _update_method = UpdateMethod.PATCH | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,30 @@ | |||
| 1 | + import pytest | ||
| 2 | + | ||
| 3 | + from gitlab import Gitlab | ||
| 4 | + from gitlab.v4.objects import Project, ProjectRegistryProtectionRule | ||
| 5 | + | ||
| 6 | + | ||
| 7 | + @pytest.fixture(scope="module", autouse=True) | ||
| 8 | + def protected_registry_feature(gl: Gitlab): | ||
| 9 | + gl.features.set(name="container_registry_protected_containers", value=True) | ||
| 10 | + | ||
| 11 | + | ||
| 12 | + def test_list_project_protected_registries(project: Project): | ||
| 13 | + rules = project.registry_protection_rules.list() | ||
| 14 | + assert isinstance(rules, list) | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + @pytest.mark.skip(reason="Not released yet") | ||
| 18 | + def test_create_project_protected_registry(project: Project): | ||
| 19 | + protected_registry = project.registry_protection_rules.create( | ||
| 20 | + { | ||
| 21 | + "repository_path_pattern": "test/image", | ||
| 22 | + "minimum_access_level_for_push": "maintainer", | ||
| 23 | + } | ||
| 24 | + ) | ||
| 25 | + assert isinstance(protected_registry, ProjectRegistryProtectionRule) | ||
| 26 | + assert protected_registry.repository_path_pattern == "test/image" | ||
| 27 | + | ||
| 28 | + protected_registry.minimum_access_level_for_push = "owner" | ||
| 29 | + protected_registry.save() | ||
| 30 | + assert protected_registry.minimum_access_level_for_push == "owner" | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,82 @@ | |||
| 1 | + """ | ||
| 2 | + GitLab API: https://docs.gitlab.com/ee/api/project_container_registry_protection_rules.html | ||
| 3 | + """ | ||
| 4 | + | ||
| 5 | + import pytest | ||
| 6 | + import responses | ||
| 7 | + | ||
| 8 | + from gitlab.v4.objects import ProjectRegistryProtectionRule | ||
| 9 | + | ||
| 10 | + protected_registry_content = { | ||
| 11 | + "id": 1, | ||
| 12 | + "project_id": 7, | ||
| 13 | + "repository_path_pattern": "test/image", | ||
| 14 | + "minimum_access_level_for_push": "maintainer", | ||
| 15 | + "minimum_access_level_for_delete": "maintainer", | ||
| 16 | + } | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + @pytest.fixture | ||
| 20 | + def resp_list_protected_registries(): | ||
| 21 | + with responses.RequestsMock() as rsps: | ||
| 22 | + rsps.add( | ||
| 23 | + method=responses.GET, | ||
| 24 | + url="http://localhost/api/v4/projects/1/registry/protection/rules", | ||
| 25 | + json=[protected_registry_content], | ||
| 26 | + content_type="application/json", | ||
| 27 | + status=200, | ||
| 28 | + ) | ||
| 29 | + yield rsps | ||
| 30 | + | ||
| 31 | + | ||
| 32 | + @pytest.fixture | ||
| 33 | + def resp_create_protected_registry(): | ||
| 34 | + with responses.RequestsMock() as rsps: | ||
| 35 | + rsps.add( | ||
| 36 | + method=responses.POST, | ||
| 37 | + url="http://localhost/api/v4/projects/1/registry/protection/rules", | ||
| 38 | + json=protected_registry_content, | ||
| 39 | + content_type="application/json", | ||
| 40 | + status=201, | ||
| 41 | + ) | ||
| 42 | + yield rsps | ||
| 43 | + | ||
| 44 | + | ||
| 45 | + @pytest.fixture | ||
| 46 | + def resp_update_protected_registry(): | ||
| 47 | + updated_content = protected_registry_content.copy() | ||
| 48 | + updated_content["repository_path_pattern"] = "abc*" | ||
| 49 | + | ||
| 50 | + with responses.RequestsMock() as rsps: | ||
| 51 | + rsps.add( | ||
| 52 | + method=responses.PATCH, | ||
| 53 | + url="http://localhost/api/v4/projects/1/registry/protection/rules/1", | ||
| 54 | + json=updated_content, | ||
| 55 | + content_type="application/json", | ||
| 56 | + status=200, | ||
| 57 | + ) | ||
| 58 | + yield rsps | ||
| 59 | + | ||
| 60 | + | ||
| 61 | + def test_list_project_protected_registries(project, resp_list_protected_registries): | ||
| 62 | + protected_registry = project.registry_protection_rules.list()[0] | ||
| 63 | + assert isinstance(protected_registry, ProjectRegistryProtectionRule) | ||
| 64 | + assert protected_registry.repository_path_pattern == "test/image" | ||
| 65 | + | ||
| 66 | + | ||
| 67 | + def test_create_project_protected_registry(project, resp_create_protected_registry): | ||
| 68 | + protected_registry = project.registry_protection_rules.create( | ||
| 69 | + { | ||
| 70 | + "repository_path_pattern": "test/image", | ||
| 71 | + "minimum_access_level_for_push": "maintainer", | ||
| 72 | + } | ||
| 73 | + ) | ||
| 74 | + assert isinstance(protected_registry, ProjectRegistryProtectionRule) | ||
| 75 | + assert protected_registry.repository_path_pattern == "test/image" | ||
| 76 | + | ||
| 77 | + | ||
| 78 | + def test_update_project_protected_registry(project, resp_update_protected_registry): | ||
| 79 | + updated = project.registry_protection_rules.update( | ||
| 80 | + 1, {"repository_path_pattern": "abc*"} | ||
| 81 | + ) | ||
| 82 | + assert updated["repository_path_pattern"] == "abc*" | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments