def test_cannot_infer_git_provider_from_url(self): with pytest.raises(GitOpsException) as ex: create_git( tmp_dir="TMP_DIR", username="******", password="******", git_user="******", git_email="GIT_EMAIL", organisation="ORG", repository_name="REPO", git_provider=None, git_provider_url="some.unknown-url.com", ) self.assertEqual("Please provide --git-provider", str(ex.value))
def test_unknown_git_provider(self): with pytest.raises(GitOpsException) as ex: create_git( tmp_dir="TMP_DIR", username="******", password="******", git_user="******", git_email="GIT_EMAIL", organisation="ORG", repository_name="REPO", git_provider="unknown", # <- unknown git_provider_url="GIT_PROVIDER_URL", ) self.assertEqual("Git provider 'unknown' is not supported.", str(ex.value))
def test_bitbucket_server_missing_git_provider_url(self): with pytest.raises(GitOpsException) as ex: create_git( tmp_dir="TMP_DIR", username="******", password="******", git_user="******", git_email="GIT_EMAIL", organisation="ORG", repository_name="REPO", git_provider="bitbucket-server", git_provider_url=None, # <- missing ) self.assertEqual( "Please provide --git-provider-url for bitbucket-server", str(ex.value))
def test_bitbucket_server(self, mock_bitbucket_git_util_constructor): mock_bitbucket_git_util = MagicMock() mock_bitbucket_git_util_constructor.return_value = mock_bitbucket_git_util git = create_git( tmp_dir="TMP_DIR", username="******", password="******", git_user="******", git_email="GIT_EMAIL", organisation="ORG", repository_name="REPO", git_provider="bitbucket-server", git_provider_url="GIT_PROVIDER_URL", ) self.assertEqual(git, mock_bitbucket_git_util) mock_bitbucket_git_util_constructor.assert_called_with( tmp_dir="TMP_DIR", username="******", password="******", git_user="******", git_email="GIT_EMAIL", organisation="ORG", repository_name="REPO", git_provider_url="GIT_PROVIDER_URL", )
def test_github_via_git_provider_url(self, mock_github_git_util_constructor): mock_github_git_util = MagicMock() mock_github_git_util_constructor.return_value = mock_github_git_util git = create_git( tmp_dir="TMP_DIR", username="******", password="******", git_user="******", git_email="GIT_EMAIL", organisation="ORG", repository_name="REPO", git_provider=None, git_provider_url="www.github.com", ) self.assertEqual(git, mock_github_git_util) mock_github_git_util_constructor.assert_called_with( tmp_dir="TMP_DIR", username="******", password="******", git_user="******", git_email="GIT_EMAIL", organisation="ORG", repository_name="REPO", )
def sync_apps_command( command, username, password, git_user, git_email, root_organisation, root_repository_name, organisation, repository_name, git_provider, git_provider_url, ): assert command == "sync-apps" apps_tmp_dir = create_tmp_dir() root_tmp_dir = create_tmp_dir() try: apps_git = create_git( username, password, git_user, git_email, organisation, repository_name, git_provider, git_provider_url, apps_tmp_dir, ) root_git = create_git( username, password, git_user, git_email, root_organisation, root_repository_name, git_provider, git_provider_url, root_tmp_dir, ) __sync_apps(apps_git, root_git) finally: delete_tmp_dir(apps_tmp_dir) delete_tmp_dir(root_tmp_dir)
def deploy_command( command, file, values, username, password, git_user, git_email, create_pr, auto_merge, single_commit, organisation, repository_name, git_provider, git_provider_url, commit_message=None, ): assert command == "deploy" tmp_dir = create_tmp_dir() try: git = create_git( username, password, git_user, git_email, organisation, repository_name, git_provider, git_provider_url, tmp_dir, ) git.checkout("master") logging.info("Master checkout successful") config_branch = f"gitopscli-deploy-{str(uuid.uuid4())[:8]}" if create_pr else "master" if create_pr: git.new_branch(config_branch) logging.info("Created branch %s", config_branch) updated_values = __update_values(git, file, values, single_commit, commit_message) if not updated_values: logging.info("All values already up-to-date. I'm done here") return git.push(config_branch) logging.info("Pushed branch %s", config_branch) finally: delete_tmp_dir(tmp_dir) if create_pr: __create_pr(git, config_branch, file, updated_values, auto_merge)
def create_pr_preview_command( command, pr_id, parent_id, username, password, git_user, git_email, organisation, repository_name, git_provider, git_provider_url, ): assert command == "create-pr-preview" apps_tmp_dir = create_tmp_dir() try: apps_git = create_git( username, password, git_user, git_email, organisation, repository_name, git_provider, git_provider_url, apps_tmp_dir, ) pr_branch = apps_git.get_pull_request_branch(pr_id) apps_git.checkout(pr_branch) logging.info("App repo PR branch %s checkout successful", pr_branch) git_hash = apps_git.get_last_commit_hash() create_preview_command( command, username, password, git_user, git_email, organisation, repository_name, git_provider, git_provider_url, git_hash, pr_branch, # <- preview_id __create_deployment_already_up_to_date_callback(parent_id, pr_id), __create_deployment_exist_callback(parent_id, pr_id, pr_branch), __create_deployment_new_callback(parent_id, pr_id, pr_branch), ) finally: delete_tmp_dir(apps_tmp_dir)
def pr_comment_command( command, text, username, password, parent_id, pr_id, organisation, repository_name, git_provider, git_provider_url, ): assert command == "add-pr-comment" apps_git = create_git( username, password, None, None, organisation, repository_name, git_provider, git_provider_url, None, ) if parent_id: logging.info( "Creating comment for PR %s as reply to comment %s with content: %s", pr_id, parent_id, text, ) else: logging.info( "Creating comment for PR %s with content: %s", pr_id, text, ) apps_git.add_pull_request_comment(pr_id, text, parent_id)
def delete_preview_command( command, username, password, git_user, git_email, organisation, repository_name, git_provider, git_provider_url, preview_id, ): assert command is not None apps_tmp_dir = create_tmp_dir() root_tmp_dir = create_tmp_dir() try: apps_git = create_git( username, password, git_user, git_email, organisation, repository_name, git_provider, git_provider_url, apps_tmp_dir, ) apps_git.checkout("master") logging.info("App repo branch master checkout successful") try: gitops_config = GitOpsConfig( apps_git.get_full_file_path(".gitops.config.yaml")) except FileNotFoundError as ex: raise GitOpsException(f"Couldn't find .gitops.config.yaml") from ex logging.info("Read GitOpsConfig: %s", gitops_config) root_git = create_git( username, password, git_user, git_email, gitops_config.team_config_org, gitops_config.team_config_repo, git_provider, git_provider_url, root_tmp_dir, ) root_git.checkout("master") logging.info("Config repo branch master checkout successful") config_branch = "master" hashed_preview_id = hashlib.sha256( preview_id.encode("utf-8")).hexdigest()[:8] preview_folder_name = gitops_config.application_name + "-" + hashed_preview_id + "-preview" logging.info("Preview folder name: %s", preview_folder_name) branch_preview_env_exists = os.path.exists( root_git.get_full_file_path(preview_folder_name)) logging.info("Is preview env already existing for branch? %s", branch_preview_env_exists) if branch_preview_env_exists: shutil.rmtree(root_git.get_full_file_path(preview_folder_name), ignore_errors=True) else: raise GitOpsException( f"There was no preview with name: {preview_folder_name}") root_git.commit( f"Delete preview environment for '{gitops_config.application_name}' and preview id '{preview_id}'." ) root_git.push(config_branch) logging.info("Pushed branch %s", config_branch) finally: delete_tmp_dir(apps_tmp_dir) delete_tmp_dir(root_tmp_dir)
def delete_pr_preview_command( command, branch, username, password, git_user, git_email, organisation, repository_name, git_provider, git_provider_url, ): assert command == "delete-pr-preview" apps_tmp_dir = create_tmp_dir() root_tmp_dir = create_tmp_dir() try: apps_git = create_git( username, password, git_user, git_email, organisation, repository_name, git_provider, git_provider_url, apps_tmp_dir, ) app_master_branch_name = "master" apps_git.checkout(app_master_branch_name) logging.info("App repo branch %s checkout successful", app_master_branch_name) try: gitops_config = GitOpsConfig( apps_git.get_full_file_path(".gitops.config.yaml")) except FileNotFoundError as ex: raise GitOpsException(f"Couldn't find .gitops.config.yaml") from ex logging.info("Read GitOpsConfig: %s", gitops_config) root_git = create_git( username, password, git_user, git_email, gitops_config.team_config_org, gitops_config.team_config_repo, git_provider, git_provider_url, root_tmp_dir, ) root_git.checkout("master") logging.info("Config repo branch master checkout successful") delete_preview_command( command, username, password, git_user, git_email, organisation, repository_name, git_provider, git_provider_url, branch, ) finally: delete_tmp_dir(apps_tmp_dir) delete_tmp_dir(root_tmp_dir)
def create_preview_command( command, username, password, git_user, git_email, organisation, repository_name, git_provider, git_provider_url, git_hash, preview_id, deployment_already_up_to_date_callback=None, deployment_exists_callback=None, deployment_new_callback=None, ): assert command is not None apps_tmp_dir = create_tmp_dir() root_tmp_dir = create_tmp_dir() try: apps_git = create_git( username, password, git_user, git_email, organisation, repository_name, git_provider, git_provider_url, apps_tmp_dir, ) apps_git.checkout(git_hash) logging.info("App repo git hash %s checkout successful", git_hash) try: gitops_config = GitOpsConfig( apps_git.get_full_file_path(".gitops.config.yaml")) except FileNotFoundError as ex: raise GitOpsException(f"Couldn't find .gitops.config.yaml") from ex logging.info("Read .gitops.config.yaml: %s", gitops_config) root_git = create_git( username, password, git_user, git_email, gitops_config.team_config_org, gitops_config.team_config_repo, git_provider, git_provider_url, root_tmp_dir, ) root_git.checkout("master") logging.info("Config repo branch master checkout successful") preview_template_folder_name = ".preview-templates/" + gitops_config.application_name if os.path.isdir( root_git.get_full_file_path(preview_template_folder_name)): logging.info("Using the preview template folder: %s", preview_template_folder_name) else: raise GitOpsException( f"The preview template folder does not exist: {preview_template_folder_name}" ) hashed_preview_id = hashlib.sha256( preview_id.encode("utf-8")).hexdigest()[:8] new_preview_folder_name = gitops_config.application_name + "-" + hashed_preview_id + "-preview" logging.info("New folder for preview: %s", new_preview_folder_name) preview_env_already_exist = os.path.isdir( root_git.get_full_file_path(new_preview_folder_name)) logging.info("Is preview env already existing? %s", preview_env_already_exist) if not preview_env_already_exist: __create_new_preview_env( git_hash, new_preview_folder_name, preview_template_folder_name, root_git, gitops_config.application_name, ) logging.info("Using image tag from git hash: %s", git_hash) route_host = None value_replaced = False for replacement in gitops_config.replacements: route_host, value_replaced = __replace_value( gitops_config, git_hash, new_preview_folder_name, replacement, root_git, route_host, hashed_preview_id, value_replaced, ) if not value_replaced: logging.info( "The image tag %s has already been deployed. Doing nothing.", git_hash) if deployment_already_up_to_date_callback: deployment_already_up_to_date_callback(apps_git, git_hash) return root_git.commit( f"Update preview environment for '{gitops_config.application_name}' and git hash '{git_hash}'." ) root_git.push("master") logging.info("Pushed branch master") if preview_env_already_exist: if deployment_exists_callback: deployment_exists_callback(apps_git, gitops_config, route_host) else: if deployment_new_callback: deployment_new_callback(apps_git, gitops_config, route_host) finally: delete_tmp_dir(apps_tmp_dir) delete_tmp_dir(root_tmp_dir)