class SnippetManager(CRUDMixin, RESTManager): _path = "/snippets" _obj_cls = Snippet _create_attrs = RequiredOptional(required=("title", "file_name", "content"), optional=("lifetime", "visibility")) _update_attrs = RequiredOptional(optional=("title", "file_name", "content", "visibility")) @cli.register_custom_action("SnippetManager") def public(self, **kwargs: Any) -> Union[RESTObjectList, List[RESTObject]]: """List all the public snippets. Args: all: If True the returned object will be a list **kwargs: Extra options to send to the server (e.g. sudo) Raises: GitlabListError: If the list could not be retrieved Returns: A generator for the snippets list """ return self.list(path="/snippets/public", **kwargs) def get(self, id: Union[str, int], lazy: bool = False, **kwargs: Any) -> Snippet: return cast(Snippet, super().get(id=id, lazy=lazy, **kwargs))
class ProjectIssueNoteManager(CRUDMixin, RESTManager): _path = "/projects/%(project_id)s/issues/%(issue_iid)s/notes" _obj_cls = ProjectIssueNote _from_parent_attrs = {"project_id": "project_id", "issue_iid": "iid"} _create_attrs = RequiredOptional(required=("body", ), optional=("created_at", )) _update_attrs = RequiredOptional(required=("body", ))
class ProjectKeyManager(CRUDMixin, RESTManager): _path = "/projects/{project_id}/deploy_keys" _obj_cls = ProjectKey _from_parent_attrs = {"project_id": "id"} _create_attrs = RequiredOptional(required=("title", "key"), optional=("can_push",)) _update_attrs = RequiredOptional(optional=("title", "can_push")) @cli.register_custom_action("ProjectKeyManager", ("key_id",)) @exc.on_http_error(exc.GitlabProjectDeployKeyError) def enable( self, key_id: int, **kwargs: Any ) -> Union[Dict[str, Any], requests.Response]: """Enable a deploy key for a project. Args: key_id: The ID of the key to enable **kwargs: Extra options to send to the server (e.g. sudo) Raises: GitlabAuthenticationError: If authentication is not correct GitlabProjectDeployKeyError: If the key could not be enabled Returns: A dict of the result. """ path = f"{self.path}/{key_id}/enable" return self.gitlab.http_post(path, **kwargs) def get(self, id: Union[str, int], lazy: bool = False, **kwargs: Any) -> ProjectKey: return cast(ProjectKey, super().get(id=id, lazy=lazy, **kwargs))
class ProjectPushRulesManager( GetWithoutIdMixin, CreateMixin, UpdateMixin, DeleteMixin, RESTManager ): _path = "/projects/%(project_id)s/push_rule" _obj_cls = ProjectPushRules _from_parent_attrs = {"project_id": "id"} _create_attrs = RequiredOptional( optional=( "deny_delete_tag", "member_check", "prevent_secrets", "commit_message_regex", "branch_name_regex", "author_email_regex", "file_name_regex", "max_file_size", ), ) _update_attrs = RequiredOptional( optional=( "deny_delete_tag", "member_check", "prevent_secrets", "commit_message_regex", "branch_name_regex", "author_email_regex", "file_name_regex", "max_file_size", ), )
class ProjectMemberManager(CRUDMixin, RESTManager): _path = "/projects/%(project_id)s/members" _obj_cls = ProjectMember _from_parent_attrs = {"project_id": "id"} _create_attrs = RequiredOptional(required=("access_level", "user_id"), optional=("expires_at", )) _update_attrs = RequiredOptional(required=("access_level", ), optional=("expires_at", )) _types = {"user_ids": types.ListAttribute} @cli.register_custom_action("ProjectMemberManager") @exc.on_http_error(exc.GitlabListError) def all(self, **kwargs): """List all the members, included inherited ones. Args: all (bool): If True, return all the items, without pagination per_page (int): Number of items to retrieve per request page (int): ID of the page to return (starts with page 1) as_list (bool): If set to False and no pagination option is defined, return a generator instead of a list **kwargs: Extra options to send to the server (e.g. sudo) Raises: GitlabAuthenticationError: If authentication is not correct GitlabListError: If the list could not be retrieved Returns: RESTObjectList: The list of members """ path = "%s/all" % self.path obj = self.gitlab.http_list(path, **kwargs) return [self._obj_cls(self, item) for item in obj]
class ProjectPushRulesManager(GetWithoutIdMixin, CreateMixin, UpdateMixin, DeleteMixin, RESTManager): _path = "/projects/{project_id}/push_rule" _obj_cls = ProjectPushRules _from_parent_attrs = {"project_id": "id"} _create_attrs = RequiredOptional(optional=( "deny_delete_tag", "member_check", "prevent_secrets", "commit_message_regex", "branch_name_regex", "author_email_regex", "file_name_regex", "max_file_size", ), ) _update_attrs = RequiredOptional(optional=( "deny_delete_tag", "member_check", "prevent_secrets", "commit_message_regex", "branch_name_regex", "author_email_regex", "file_name_regex", "max_file_size", ), ) def get(self, id: Optional[Union[int, str]] = None, **kwargs: Any) -> Optional[ProjectPushRules]: return cast(Optional[ProjectPushRules], super().get(id=id, **kwargs))
class GroupEpicIssueManager(ListMixin, CreateMixin, UpdateMixin, DeleteMixin, RESTManager): _path = "/groups/%(group_id)s/epics/%(epic_iid)s/issues" _obj_cls = GroupEpicIssue _from_parent_attrs = {"group_id": "group_id", "epic_iid": "iid"} _create_attrs = RequiredOptional(required=("issue_id", )) _update_attrs = RequiredOptional(optional=("move_before_id", "move_after_id")) @exc.on_http_error(exc.GitlabCreateError) def create(self, data, **kwargs): """Create a new object. Args: data (dict): Parameters to send to the server to create the resource **kwargs: Extra options to send to the server (e.g. sudo) Raises: GitlabAuthenticationError: If authentication is not correct GitlabCreateError: If the server cannot perform the request Returns: RESTObject: A new instance of the manage object class build with the data sent by the server """ CreateMixin._check_missing_create_attrs(self, data) path = "%s/%s" % (self.path, data.pop("issue_id")) server_data = self.gitlab.http_post(path, **kwargs) # The epic_issue_id attribute doesn't exist when creating the resource, # but is used everywhere elese. Let's create it to be consistent client # side server_data["epic_issue_id"] = server_data["id"] return self._obj_cls(self, server_data)
class ProjectPagesDomainManager(CRUDMixin, RESTManager): _path = "/projects/%(project_id)s/pages/domains" _obj_cls = ProjectPagesDomain _from_parent_attrs = {"project_id": "id"} _create_attrs = RequiredOptional(required=("domain", ), optional=("certificate", "key")) _update_attrs = RequiredOptional(optional=("certificate", "key"))
class ProjectMergeRequestManager(CRUDMixin, RESTManager): _path = "/projects/%(project_id)s/merge_requests" _obj_cls = ProjectMergeRequest _from_parent_attrs = {"project_id": "id"} _create_attrs = RequiredOptional( required=("source_branch", "target_branch", "title"), optional=( "assignee_id", "description", "target_project_id", "labels", "milestone_id", "remove_source_branch", "allow_maintainer_to_push", "squash", ), ) _update_attrs = RequiredOptional(optional=( "target_branch", "assignee_id", "title", "description", "state_event", "labels", "milestone_id", "remove_source_branch", "discussion_locked", "allow_maintainer_to_push", "squash", ), ) _list_filters = ( "state", "order_by", "sort", "milestone", "view", "labels", "created_after", "created_before", "updated_after", "updated_before", "scope", "iids", "author_id", "assignee_id", "approver_ids", "approved_by_ids", "my_reaction_emoji", "source_branch", "target_branch", "search", "wip", ) _types = { "approver_ids": types.ListAttribute, "approved_by_ids": types.ListAttribute, "iids": types.ListAttribute, "labels": types.ListAttribute, }
class ProjectPipelineScheduleManager(CRUDMixin, RESTManager): _path = "/projects/%(project_id)s/pipeline_schedules" _obj_cls = ProjectPipelineSchedule _from_parent_attrs = {"project_id": "id"} _create_attrs = RequiredOptional(required=("description", "ref", "cron"), optional=("cron_timezone", "active")) _update_attrs = RequiredOptional(optional=("description", "ref", "cron", "cron_timezone", "active"), )
class ProjectPipelineScheduleVariableManager( CreateMixin, UpdateMixin, DeleteMixin, RESTManager ): _path = "/projects/{project_id}/pipeline_schedules/{pipeline_schedule_id}/variables" _obj_cls = ProjectPipelineScheduleVariable _from_parent_attrs = {"project_id": "project_id", "pipeline_schedule_id": "id"} _create_attrs = RequiredOptional(required=("key", "value")) _update_attrs = RequiredOptional(required=("key", "value"))
class ProjectRemoteMirrorManager(ListMixin, CreateMixin, UpdateMixin, RESTManager): _path = "/projects/%(project_id)s/remote_mirrors" _obj_cls = ProjectRemoteMirror _from_parent_attrs = {"project_id": "id"} _create_attrs = RequiredOptional( required=("url",), optional=("enabled", "only_protected_branches") ) _update_attrs = RequiredOptional(optional=("enabled", "only_protected_branches"))
class ProjectEnvironmentManager(RetrieveMixin, CreateMixin, UpdateMixin, DeleteMixin, RESTManager): _path = "/projects/%(project_id)s/environments" _obj_cls = ProjectEnvironment _from_parent_attrs = {"project_id": "id"} _create_attrs = RequiredOptional(required=("name", ), optional=("external_url", )) _update_attrs = RequiredOptional(optional=("name", "external_url"))
class ProjectReleaseLinkManager(CRUDMixin, RESTManager): _path = "/projects/%(project_id)s/releases/%(tag_name)s/assets/links" _obj_cls = ProjectReleaseLink _from_parent_attrs = {"project_id": "project_id", "tag_name": "tag_name"} _create_attrs = RequiredOptional( required=("name", "url"), optional=("filepath", "link_type") ) _update_attrs = RequiredOptional(optional=("name", "url", "filepath", "link_type"))
class ProjectMergeRequestDiscussionManager(RetrieveMixin, CreateMixin, UpdateMixin, RESTManager): _path = "/projects/%(project_id)s/merge_requests/%(mr_iid)s/discussions" _obj_cls = ProjectMergeRequestDiscussion _from_parent_attrs = {"project_id": "project_id", "mr_iid": "iid"} _create_attrs = RequiredOptional(required=("body", ), optional=("created_at", "position")) _update_attrs = RequiredOptional(required=("resolved", ))
class GroupWikiManager(CRUDMixin, RESTManager): _path = "/groups/%(group_id)s/wikis" _obj_cls = GroupWiki _from_parent_attrs = {"group_id": "id"} _create_attrs = RequiredOptional(required=("title", "content"), optional=("format", )) _update_attrs = RequiredOptional(optional=("title", "content", "format")) _list_filters = ("with_content", )
class GroupMemberManager(CRUDMixin, RESTManager): _path = "/groups/%(group_id)s/members" _obj_cls = GroupMember _from_parent_attrs = {"group_id": "id"} _create_attrs = RequiredOptional(required=("access_level", "user_id"), optional=("expires_at", )) _update_attrs = RequiredOptional(required=("access_level", ), optional=("expires_at", )) _types = {"user_ids": types.ListAttribute}
class ProjectMemberManager(MemberAllMixin, CRUDMixin, RESTManager): _path = "/projects/%(project_id)s/members" _obj_cls = ProjectMember _from_parent_attrs = {"project_id": "id"} _create_attrs = RequiredOptional(required=("access_level", "user_id"), optional=("expires_at", )) _update_attrs = RequiredOptional(required=("access_level", ), optional=("expires_at", )) _types = {"user_ids": types.ListAttribute}
class VariableManager(CRUDMixin, RESTManager): _path = "/admin/ci/variables" _obj_cls = Variable _create_attrs = RequiredOptional( required=("key", "value"), optional=("protected", "variable_type", "masked") ) _update_attrs = RequiredOptional( required=("key", "value"), optional=("protected", "variable_type", "masked") )
class BroadcastMessageManager(CRUDMixin, RESTManager): _path = "/broadcast_messages" _obj_cls = BroadcastMessage _create_attrs = RequiredOptional(required=("message", ), optional=("starts_at", "ends_at", "color", "font")) _update_attrs = RequiredOptional(optional=("message", "starts_at", "ends_at", "color", "font"))
class ProjectIssueManager(CRUDMixin, RESTManager): _path = "/projects/{project_id}/issues" _obj_cls = ProjectIssue _from_parent_attrs = {"project_id": "id"} _list_filters = ( "iids", "state", "labels", "milestone", "scope", "author_id", "assignee_id", "my_reaction_emoji", "order_by", "sort", "search", "created_after", "created_before", "updated_after", "updated_before", ) _create_attrs = RequiredOptional( required=("title", ), optional=( "description", "confidential", "assignee_ids", "assignee_id", "milestone_id", "labels", "created_at", "due_date", "merge_request_to_resolve_discussions_of", "discussion_to_resolve", ), ) _update_attrs = RequiredOptional(optional=( "title", "description", "confidential", "assignee_ids", "assignee_id", "milestone_id", "labels", "state_event", "updated_at", "due_date", "discussion_locked", ), ) _types = {"iids": types.ListAttribute, "labels": types.ListAttribute} def get(self, id: Union[str, int], lazy: bool = False, **kwargs: Any) -> ProjectIssue: return cast(ProjectIssue, super().get(id=id, lazy=lazy, **kwargs))
class ProjectSnippetManager(CRUDMixin, RESTManager): _path = "/projects/%(project_id)s/snippets" _obj_cls = ProjectSnippet _from_parent_attrs = {"project_id": "id"} _create_attrs = RequiredOptional( required=("title", "file_name", "content", "visibility"), optional=("description", ), ) _update_attrs = RequiredOptional(optional=("title", "file_name", "content", "visibility", "description"), )
class ProjectReleaseManager(CRUDMixin, RESTManager): _path = "/projects/%(project_id)s/releases" _obj_cls = ProjectRelease _from_parent_attrs = {"project_id": "id"} _create_attrs = RequiredOptional( required=("name", "tag_name", "description"), optional=("ref", "assets") ) _update_attrs = RequiredOptional( optional=("name", "description", "milestones", "released_at") )
class GroupVariableManager(CRUDMixin, RESTManager): _path = "/groups/%(group_id)s/variables" _obj_cls = GroupVariable _from_parent_attrs = {"group_id": "id"} _create_attrs = RequiredOptional( required=("key", "value"), optional=("protected", "variable_type", "masked") ) _update_attrs = RequiredOptional( required=("key", "value"), optional=("protected", "variable_type", "masked") )
class ProjectLabelManager(RetrieveMixin, CreateMixin, UpdateMixin, DeleteMixin, RESTManager): _path = "/projects/{project_id}/labels" _obj_cls = ProjectLabel _from_parent_attrs = {"project_id": "id"} _create_attrs = RequiredOptional(required=("name", "color"), optional=("description", "priority")) _update_attrs = RequiredOptional(required=("name", ), optional=("new_name", "color", "description", "priority")) def get(self, id: Union[str, int], lazy: bool = False, **kwargs: Any) -> ProjectLabel: return cast(ProjectLabel, super().get(id=id, lazy=lazy, **kwargs)) # Update without ID. # NOTE(jlvillal): Signature doesn't match UpdateMixin.update() so ignore # type error def update( # type: ignore self, name: Optional[str], new_data: Optional[Dict[str, Any]] = None, **kwargs: Any) -> Dict[str, Any]: """Update a Label on the server. Args: name: The name of the label **kwargs: Extra options to send to the server (e.g. sudo) """ new_data = new_data or {} if name: new_data["name"] = name return super().update(id=None, new_data=new_data, **kwargs) # Delete without ID. @exc.on_http_error(exc.GitlabDeleteError) # NOTE(jlvillal): Signature doesn't match DeleteMixin.delete() so ignore # type error def delete(self, name: str, **kwargs: Any) -> None: # type: ignore """Delete a Label on the server. Args: name: The name of the label **kwargs: Extra options to send to the server (e.g. sudo) Raises: GitlabAuthenticationError: If authentication is not correct GitlabDeleteError: If the server cannot perform the request """ if TYPE_CHECKING: assert self.path is not None self.gitlab.http_delete(self.path, query_data={"name": name}, **kwargs)
class GroupMilestoneManager(CRUDMixin, RESTManager): _path = "/groups/%(group_id)s/milestones" _obj_cls = GroupMilestone _from_parent_attrs = {"group_id": "id"} _create_attrs = RequiredOptional(required=("title", ), optional=("description", "due_date", "start_date")) _update_attrs = RequiredOptional(optional=("title", "description", "due_date", "start_date", "state_event"), ) _list_filters = ("iids", "state", "search")
class ProjectTriggerManager(CRUDMixin, RESTManager): _path = "/projects/{project_id}/triggers" _obj_cls = ProjectTrigger _from_parent_attrs = {"project_id": "id"} _create_attrs = RequiredOptional(required=("description", )) _update_attrs = RequiredOptional(required=("description", )) def get(self, id: Union[str, int], lazy: bool = False, **kwargs: Any) -> ProjectTrigger: return cast(ProjectTrigger, super().get(id=id, lazy=lazy, **kwargs))
class ProjectBadgeManager(BadgeRenderMixin, CRUDMixin, RESTManager): _path = "/projects/{project_id}/badges" _obj_cls = ProjectBadge _from_parent_attrs = {"project_id": "id"} _create_attrs = RequiredOptional(required=("link_url", "image_url")) _update_attrs = RequiredOptional(optional=("link_url", "image_url")) def get(self, id: Union[str, int], lazy: bool = False, **kwargs: Any) -> ProjectBadge: return cast(ProjectBadge, super().get(id=id, lazy=lazy, **kwargs))
class ProjectBoardListManager(CRUDMixin, RESTManager): _path = "/projects/{project_id}/boards/{board_id}/lists" _obj_cls = ProjectBoardList _from_parent_attrs = {"project_id": "project_id", "board_id": "id"} _create_attrs = RequiredOptional(required=("label_id", )) _update_attrs = RequiredOptional(required=("position", )) def get(self, id: Union[str, int], lazy: bool = False, **kwargs: Any) -> ProjectBoardList: return cast(ProjectBoardList, super().get(id=id, lazy=lazy, **kwargs))
class ProjectVariableManager(CRUDMixin, RESTManager): _path = "/projects/%(project_id)s/variables" _obj_cls = ProjectVariable _from_parent_attrs = {"project_id": "id"} _create_attrs = RequiredOptional( required=("key", "value"), optional=("protected", "variable_type", "masked", "environment_scope"), ) _update_attrs = RequiredOptional( required=("key", "value"), optional=("protected", "variable_type", "masked", "environment_scope"), )