Skip to content

GitLab

Sample Commands

on-gitlab --projects
on-gitlab --runners
on-gitlab --keys

Perform GitLab integrations

Source code in linecaspy/gitlab/gitlab.py
class GitlabClass:
    """Perform GitLab integrations"""

    def __init__(self, token, url="https://gitlab.com", debug=False, tables=True):
        """Initializes GitLab class

        Args:
            token (string): GitLab token
            url (string): GitLab server
            debug (boolean): Whether or not to use verbose logging
            tables (boolean): Whether or not print Pretty Tables
        """
        self.token = token
        self.gitlab_url = url
        self.debug = debug
        self.pretty_table = tables
        self.hf = HelperFunctions()
        self.gl = gitlab.Gitlab(url, private_token=self.token, pagination="keyset", order_by="id", per_page=20)
        self.headers = {"Content-Type": "application/json", "Private-Token": self.token}

    def delete_runners(self, runners):
        """Delete obselete GitLab Runners

        Args:
            runners (list): of dictionaries
        """
        for runner in runners:
            if runner.get("status", "") == "offline" and "gitlab-runner-gitlab-runner" in runner.get("description", ""):
                log.info(f"Will delete: {runner}")
                self.gl.runners.delete(runner.get("id"))
            else:
                log.debug(f"Keeping: {runner}")

    def get_projects(self):
        """Gets GitLab Project data

        Returns:
            list: of dictionaries on all projects
        """
        all_projects = []
        projects = self.gl.projects.list(owned=True, as_list=False)
        for project in projects:
            project_dict = {}
            project_dict["default_branch"] = project.attributes.get("default_branch")
            project_dict["id"] = project.attributes.get("id")
            project_dict["name"] = project.attributes.get("name").lower()
            project_dict["namespace"] = project.attributes.get("namespace").get("name").lower()
            project_dict["namespace_kind"] = project.attributes.get("namespace").get("kind")  # group/user
            project_dict["path_with_namespace"] = project.attributes.get("path_with_namespace")
            project_dict["web_url"] = project.attributes.get("web_url")
            try:
                # BUG: commit count tops off at 20
                project_dict["commit_count"] = len(project.commits.list())
            except Exception as e:
                # "No repository" will trigger this
                log.error(f"{project_dict['id']} / {project_dict['name']} commint_count error with: {e}")
                project_dict["commit_count"] = 0
            all_projects.append(project_dict)
            if self.pretty_table:
                self.ppt.add_row(
                    [
                        project_dict["namespace"],
                        project_dict["name"],
                        project_dict["default_branch"],
                        project_dict["commit_count"],
                        project_dict["web_url"],
                    ]
                )
        if self.debug:
            log.info("all_projects:")
            pprint(all_projects)
        log.info(f"There are {len(all_projects)} total projects")
        return all_projects

    def get_runners(self):
        """Gets list of all Runners

        Returns:
            list: of dictionaries on all runners
        """
        all_runners = []
        runners = self.gl.runners.list(as_list=False)
        for runner in runners:
            runner_dict = {}
            runner_dict["description"] = runner.attributes.get("description")
            runner_dict["id"] = runner.attributes.get("id")
            runner_dict["ip_address"] = runner.attributes.get("ip_address")
            runner_dict["name"] = runner.attributes.get("name")
            runner_dict["runner_type"] = runner.attributes.get("runner_type")
            runner_dict["status"] = runner.attributes.get("status")
            all_runners.append(runner_dict)
            if self.pretty_table:
                self.ppr.add_row(
                    [
                        runner_dict["name"],
                        runner_dict["id"],
                        runner_dict["status"],
                        runner_dict["ip_address"],
                        runner_dict["description"],
                    ]
                )
        if self.debug:
            log.info("all_runners:")
            pprint(all_runners)
        log.debug(f"There are {len(all_runners)} total runners")
        return all_runners

    def get_ssh_keys(self):
        """Gets list of SSH Keys

        Returns:
            list: of dictionaries on all SSH Keys
        """
        url = f"{self.gitlab_url}/api/v4/user/keys"
        log.info(f"Calling: {url}")
        r = self.hf.requests_get_url(url, self.headers, 200)
        if r:
            keys = self.hf.requests_return_json_response(r)
            if keys:
                if self.pretty_table:
                    for key in keys:
                        self.ppk.add_row(
                            [
                                key.get("title"),
                                key.get("created_at"),
                            ]
                        )
                if self.debug:
                    log.info("keys:")
                    pprint(keys)
                return keys

    def get_public_key_contents(self, override_home_path=None, file_path="/.ssh/id_rsa.pub"):
        """Read public key file"""
        if override_home_path:
            home = override_home_path
        else:
            home = str(Path.home())
        with open(home + file_path, "r") as file:
            self.public_key = file.read()
        log.debug(f"Public Key is: {self.public_key}")

    def key_entry(self):
        """Displays pretty table of GitLab Projects"""
        fields = ["Title", "Created At"]
        alignments = {"Title": "l"}
        self.ppk = self.hf.pretty_table_create(fields, **alignments)
        keys = self.get_ssh_keys()
        self.hf.pretty_table_print(self.ppk, sort_key="Title")
        # TODO: figure out what I want to do here
        if not any(key["title"] == "personal" for key in keys):
            self.get_public_key_contents()
            # TODO: write logic to create a key
        else:
            log.info("desired key already exists")

    def pprint_projects(self):
        """Displays pretty table of GitLab Projects"""
        fields = ["Namespace", "Name", "Default Branch", "Commit Count", "URL"]
        alignments = {"Namespace": "l", "Name": "l", "URL": "l"}
        self.ppt = self.hf.pretty_table_create(fields, **alignments)
        self.get_projects()
        self.hf.pretty_table_print(self.ppt, sort_key="Name")

    def pprint_runners(self):
        """Displays pretty table of GitLab Runners"""
        # TODO: get runner tags
        fields = ["Name", "ID", "Status", "IP", "Description"]
        alignments = {"Name": "l"}
        self.ppr = self.hf.pretty_table_create(fields, **alignments)
        self.get_runners()
        self.hf.pretty_table_print(self.ppr, sort_key="Name")

__init__(self, token, url='https://gitlab.com', debug=False, tables=True) special

Initializes GitLab class

Parameters:

Name Type Description Default
token string

GitLab token

required
url string

GitLab server

'https://gitlab.com'
debug boolean

Whether or not to use verbose logging

False
tables boolean

Whether or not print Pretty Tables

True
Source code in linecaspy/gitlab/gitlab.py
def __init__(self, token, url="https://gitlab.com", debug=False, tables=True):
    """Initializes GitLab class

    Args:
        token (string): GitLab token
        url (string): GitLab server
        debug (boolean): Whether or not to use verbose logging
        tables (boolean): Whether or not print Pretty Tables
    """
    self.token = token
    self.gitlab_url = url
    self.debug = debug
    self.pretty_table = tables
    self.hf = HelperFunctions()
    self.gl = gitlab.Gitlab(url, private_token=self.token, pagination="keyset", order_by="id", per_page=20)
    self.headers = {"Content-Type": "application/json", "Private-Token": self.token}

delete_runners(self, runners)

Delete obselete GitLab Runners

Parameters:

Name Type Description Default
runners list

of dictionaries

required
Source code in linecaspy/gitlab/gitlab.py
def delete_runners(self, runners):
    """Delete obselete GitLab Runners

    Args:
        runners (list): of dictionaries
    """
    for runner in runners:
        if runner.get("status", "") == "offline" and "gitlab-runner-gitlab-runner" in runner.get("description", ""):
            log.info(f"Will delete: {runner}")
            self.gl.runners.delete(runner.get("id"))
        else:
            log.debug(f"Keeping: {runner}")

get_projects(self)

Gets GitLab Project data

Returns:

Type Description
list

of dictionaries on all projects

Source code in linecaspy/gitlab/gitlab.py
def get_projects(self):
    """Gets GitLab Project data

    Returns:
        list: of dictionaries on all projects
    """
    all_projects = []
    projects = self.gl.projects.list(owned=True, as_list=False)
    for project in projects:
        project_dict = {}
        project_dict["default_branch"] = project.attributes.get("default_branch")
        project_dict["id"] = project.attributes.get("id")
        project_dict["name"] = project.attributes.get("name").lower()
        project_dict["namespace"] = project.attributes.get("namespace").get("name").lower()
        project_dict["namespace_kind"] = project.attributes.get("namespace").get("kind")  # group/user
        project_dict["path_with_namespace"] = project.attributes.get("path_with_namespace")
        project_dict["web_url"] = project.attributes.get("web_url")
        try:
            # BUG: commit count tops off at 20
            project_dict["commit_count"] = len(project.commits.list())
        except Exception as e:
            # "No repository" will trigger this
            log.error(f"{project_dict['id']} / {project_dict['name']} commint_count error with: {e}")
            project_dict["commit_count"] = 0
        all_projects.append(project_dict)
        if self.pretty_table:
            self.ppt.add_row(
                [
                    project_dict["namespace"],
                    project_dict["name"],
                    project_dict["default_branch"],
                    project_dict["commit_count"],
                    project_dict["web_url"],
                ]
            )
    if self.debug:
        log.info("all_projects:")
        pprint(all_projects)
    log.info(f"There are {len(all_projects)} total projects")
    return all_projects

get_public_key_contents(self, override_home_path=None, file_path='/.ssh/id_rsa.pub')

Read public key file

Source code in linecaspy/gitlab/gitlab.py
def get_public_key_contents(self, override_home_path=None, file_path="/.ssh/id_rsa.pub"):
    """Read public key file"""
    if override_home_path:
        home = override_home_path
    else:
        home = str(Path.home())
    with open(home + file_path, "r") as file:
        self.public_key = file.read()
    log.debug(f"Public Key is: {self.public_key}")

get_runners(self)

Gets list of all Runners

Returns:

Type Description
list

of dictionaries on all runners

Source code in linecaspy/gitlab/gitlab.py
def get_runners(self):
    """Gets list of all Runners

    Returns:
        list: of dictionaries on all runners
    """
    all_runners = []
    runners = self.gl.runners.list(as_list=False)
    for runner in runners:
        runner_dict = {}
        runner_dict["description"] = runner.attributes.get("description")
        runner_dict["id"] = runner.attributes.get("id")
        runner_dict["ip_address"] = runner.attributes.get("ip_address")
        runner_dict["name"] = runner.attributes.get("name")
        runner_dict["runner_type"] = runner.attributes.get("runner_type")
        runner_dict["status"] = runner.attributes.get("status")
        all_runners.append(runner_dict)
        if self.pretty_table:
            self.ppr.add_row(
                [
                    runner_dict["name"],
                    runner_dict["id"],
                    runner_dict["status"],
                    runner_dict["ip_address"],
                    runner_dict["description"],
                ]
            )
    if self.debug:
        log.info("all_runners:")
        pprint(all_runners)
    log.debug(f"There are {len(all_runners)} total runners")
    return all_runners

get_ssh_keys(self)

Gets list of SSH Keys

Returns:

Type Description
list

of dictionaries on all SSH Keys

Source code in linecaspy/gitlab/gitlab.py
def get_ssh_keys(self):
    """Gets list of SSH Keys

    Returns:
        list: of dictionaries on all SSH Keys
    """
    url = f"{self.gitlab_url}/api/v4/user/keys"
    log.info(f"Calling: {url}")
    r = self.hf.requests_get_url(url, self.headers, 200)
    if r:
        keys = self.hf.requests_return_json_response(r)
        if keys:
            if self.pretty_table:
                for key in keys:
                    self.ppk.add_row(
                        [
                            key.get("title"),
                            key.get("created_at"),
                        ]
                    )
            if self.debug:
                log.info("keys:")
                pprint(keys)
            return keys

key_entry(self)

Displays pretty table of GitLab Projects

Source code in linecaspy/gitlab/gitlab.py
def key_entry(self):
    """Displays pretty table of GitLab Projects"""
    fields = ["Title", "Created At"]
    alignments = {"Title": "l"}
    self.ppk = self.hf.pretty_table_create(fields, **alignments)
    keys = self.get_ssh_keys()
    self.hf.pretty_table_print(self.ppk, sort_key="Title")
    # TODO: figure out what I want to do here
    if not any(key["title"] == "personal" for key in keys):
        self.get_public_key_contents()
        # TODO: write logic to create a key
    else:
        log.info("desired key already exists")

pprint_projects(self)

Displays pretty table of GitLab Projects

Source code in linecaspy/gitlab/gitlab.py
def pprint_projects(self):
    """Displays pretty table of GitLab Projects"""
    fields = ["Namespace", "Name", "Default Branch", "Commit Count", "URL"]
    alignments = {"Namespace": "l", "Name": "l", "URL": "l"}
    self.ppt = self.hf.pretty_table_create(fields, **alignments)
    self.get_projects()
    self.hf.pretty_table_print(self.ppt, sort_key="Name")

pprint_runners(self)

Displays pretty table of GitLab Runners

Source code in linecaspy/gitlab/gitlab.py
def pprint_runners(self):
    """Displays pretty table of GitLab Runners"""
    # TODO: get runner tags
    fields = ["Name", "ID", "Status", "IP", "Description"]
    alignments = {"Name": "l"}
    self.ppr = self.hf.pretty_table_create(fields, **alignments)
    self.get_runners()
    self.hf.pretty_table_print(self.ppr, sort_key="Name")