summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNejc Habjan <nejc.habjan@siemens.com>2022-06-22 16:00:46 +0200
committerGitHub <noreply@github.com>2022-06-22 16:00:46 +0200
commit1feabc08171afaa08cea3545eb70c169231ab5d1 (patch)
tree0a1f3b1e479892e7149e6d0c00c9f3c6245ad4f0
parent8342f53854c0accf5bc8ce9a9be64a5f335eed07 (diff)
parent1dc9d0f91757eed9f28f0c7172654b9b2a730216 (diff)
downloadgitlab-1feabc08171afaa08cea3545eb70c169231ab5d1.tar.gz
Merge pull request #2084 from calve/protected-environments
feat: Add support for Protected Environments
-rw-r--r--docs/api-objects.rst1
-rw-r--r--docs/gl_objects/environments.rst4
-rw-r--r--docs/gl_objects/protected_environments.rst45
-rw-r--r--gitlab/v4/objects/environments.py29
-rw-r--r--gitlab/v4/objects/projects.py6
-rw-r--r--tests/unit/objects/test_environments.py27
6 files changed, 109 insertions, 3 deletions
diff --git a/docs/api-objects.rst b/docs/api-objects.rst
index 5349148..e313bd8 100644
--- a/docs/api-objects.rst
+++ b/docs/api-objects.rst
@@ -43,6 +43,7 @@ API examples
gl_objects/projects
gl_objects/project_access_tokens
gl_objects/protected_branches
+ gl_objects/protected_environments
gl_objects/releases
gl_objects/runners
gl_objects/remote_mirrors
diff --git a/docs/gl_objects/environments.rst b/docs/gl_objects/environments.rst
index 6edde12..e6e3d72 100644
--- a/docs/gl_objects/environments.rst
+++ b/docs/gl_objects/environments.rst
@@ -39,6 +39,8 @@ Delete an environment for a project::
# or
environment.delete()
-Stop an environments::
+Stop an environment::
environment.stop()
+
+To manage protected environments, see :doc:`/gl_objects/protected_environments`.
diff --git a/docs/gl_objects/protected_environments.rst b/docs/gl_objects/protected_environments.rst
new file mode 100644
index 0000000..a05cc1d
--- /dev/null
+++ b/docs/gl_objects/protected_environments.rst
@@ -0,0 +1,45 @@
+######################
+Protected environments
+######################
+
+You can list and manage protected environments in a project.
+
+References
+----------
+
+* v4 API:
+
+ + :class:`gitlab.v4.objects.ProjectProtectedEnvironment`
+ + :class:`gitlab.v4.objects.ProjectProtectedEnvironmentManager`
+ + :attr:`gitlab.v4.objects.Project.protected_environment`
+
+* GitLab API: https://docs.gitlab.com/ee/api/protected_environments.html
+
+Examples
+--------
+
+Get the list of protected environments for a project::
+
+ p_environments = project.protected_environments.list()
+
+Get a single protected environment::
+
+ p_environments = project.protected_environments.get('production')
+
+Protect an existing environment::
+
+ p_environment = project.protected_environments.create(
+ {
+ 'name': 'production',
+ 'deploy_access_levels': [
+ {'access_level': 40}
+ ],
+ }
+ )
+
+
+Unprotect a protected environment::
+
+ p_environment = project.protected_environments.delete('production')
+ # or
+ p_environment.delete()
diff --git a/gitlab/v4/objects/environments.py b/gitlab/v4/objects/environments.py
index 7e2089f..a8bd9d5 100644
--- a/gitlab/v4/objects/environments.py
+++ b/gitlab/v4/objects/environments.py
@@ -18,6 +18,8 @@ from gitlab.types import RequiredOptional
__all__ = [
"ProjectEnvironment",
"ProjectEnvironmentManager",
+ "ProjectProtectedEnvironment",
+ "ProjectProtectedEnvironmentManager",
]
@@ -55,3 +57,30 @@ class ProjectEnvironmentManager(
self, id: Union[str, int], lazy: bool = False, **kwargs: Any
) -> ProjectEnvironment:
return cast(ProjectEnvironment, super().get(id=id, lazy=lazy, **kwargs))
+
+
+class ProjectProtectedEnvironment(ObjectDeleteMixin, RESTObject):
+ _id_attr = "name"
+ _repr_attr = "name"
+
+
+class ProjectProtectedEnvironmentManager(
+ RetrieveMixin, CreateMixin, DeleteMixin, RESTManager
+):
+ _path = "/projects/{project_id}/protected_environments"
+ _obj_cls = ProjectProtectedEnvironment
+ _from_parent_attrs = {"project_id": "id"}
+ _create_attrs = RequiredOptional(
+ required=(
+ "name",
+ "deploy_access_levels",
+ ),
+ optional=("required_approval_count", "approval_rules"),
+ )
+
+ def get(
+ self, id: Union[str, int], lazy: bool = False, **kwargs: Any
+ ) -> ProjectProtectedEnvironment:
+ return cast(
+ ProjectProtectedEnvironment, super().get(id=id, lazy=lazy, **kwargs)
+ )
diff --git a/gitlab/v4/objects/projects.py b/gitlab/v4/objects/projects.py
index 8674ee6..f32cf22 100644
--- a/gitlab/v4/objects/projects.py
+++ b/gitlab/v4/objects/projects.py
@@ -31,7 +31,10 @@ from .custom_attributes import ProjectCustomAttributeManager # noqa: F401
from .deploy_keys import ProjectKeyManager # noqa: F401
from .deploy_tokens import ProjectDeployTokenManager # noqa: F401
from .deployments import ProjectDeploymentManager # noqa: F401
-from .environments import ProjectEnvironmentManager # noqa: F401
+from .environments import ( # noqa: F401
+ ProjectEnvironmentManager,
+ ProjectProtectedEnvironmentManager,
+)
from .events import ProjectEventManager # noqa: F401
from .export_import import ProjectExportManager, ProjectImportManager # noqa: F401
from .files import ProjectFileManager # noqa: F401
@@ -175,6 +178,7 @@ class Project(RefreshMixin, SaveMixin, ObjectDeleteMixin, RepositoryMixin, RESTO
pagesdomains: ProjectPagesDomainManager
pipelines: ProjectPipelineManager
pipelineschedules: ProjectPipelineScheduleManager
+ protected_environments: ProjectProtectedEnvironmentManager
protectedbranches: ProjectProtectedBranchManager
protectedtags: ProjectProtectedTagManager
pushrules: ProjectPushRulesManager
diff --git a/tests/unit/objects/test_environments.py b/tests/unit/objects/test_environments.py
index b49a1db..5501471 100644
--- a/tests/unit/objects/test_environments.py
+++ b/tests/unit/objects/test_environments.py
@@ -4,7 +4,7 @@ GitLab API: https://docs.gitlab.com/ce/api/environments.html
import pytest
import responses
-from gitlab.v4.objects import ProjectEnvironment
+from gitlab.v4.objects import ProjectEnvironment, ProjectProtectedEnvironment
@pytest.fixture
@@ -22,9 +22,34 @@ def resp_get_environment():
yield rsps
+@pytest.fixture
+def resp_get_protected_environment():
+ content = {
+ "name": "protected_environment_name",
+ "last_deployment": "my birthday",
+ }
+
+ with responses.RequestsMock() as rsps:
+ rsps.add(
+ method=responses.GET,
+ url="http://localhost/api/v4/projects/1/protected_environments/2",
+ json=content,
+ content_type="application/json",
+ status=200,
+ )
+ yield rsps
+
+
def test_project_environments(project, resp_get_environment):
environment = project.environments.get(1)
assert isinstance(environment, ProjectEnvironment)
assert environment.id == 1
assert environment.last_deployment == "sometime"
assert environment.name == "environment_name"
+
+
+def test_project_protected_environments(project, resp_get_protected_environment):
+ protected_environment = project.protected_environments.get(2)
+ assert isinstance(protected_environment, ProjectProtectedEnvironment)
+ assert protected_environment.last_deployment == "my birthday"
+ assert protected_environment.name == "protected_environment_name"