Beispiel #1
0
class TestProjects(unittest.TestCase):
    """
    Test case:
        Tag Retention
    Setup:
        Create Project test-retention
        Push image test1:1.0, test1:2.0, test1:3.0,latest, test2:1.0, test2:latest, test3:1.0, test4:1.0
    Test Steps:
        1. Create Retention Policy
        2. Add rule "For the repositories matching **, retain always with tags matching latest*"
        3. Add rule "For the repositories matching test3*, retain always with tags matching **"
        4. Dry run, check execution and tasks
        5. Real run, check images retained
    Tear Down:
        1. Delete project test-retention
    """
    @suppress_urllib3_warning
    def setUp(self):
        self.user = User()
        self.system = System()
        self.repo = Repository()
        self.project = Project()
        self.retention = Retention()
        self.artifact = Artifact()
        self.repo_name_1 = "test1"
        self.repo_name_2 = "test2"

    @unittest.skipIf(TEARDOWN == False, "Test data won't be erased.")
    def tearDown(self):
        #TODO delete_repository will fail when no tags left anymore
        resp = self.repo.list_repositories(TestProjects.project_src_repo_name,
                                           **TestProjects.USER_RA_CLIENT)
        for repo in resp:
            self.repo.delete_repository(TestProjects.project_src_repo_name,
                                        repo.name.split('/')[1],
                                        **TestProjects.USER_RA_CLIENT)
        self.project.delete_project(TestProjects.project_src_repo_id,
                                    **TestProjects.USER_RA_CLIENT)
        self.user.delete_user(TestProjects.user_ra_id, **ADMIN_CLIENT)
        print("Case completed")

    def testTagRetention(self):
        user_ra_password = "******"
        user_ra_id, user_ra_name = self.user.create_user(
            user_password=user_ra_password, **ADMIN_CLIENT)
        print("Created user: %s, id: %s" % (user_ra_name, user_ra_id))
        TestProjects.USER_RA_CLIENT = dict(endpoint=ADMIN_CLIENT["endpoint"],
                                           username=user_ra_name,
                                           password=user_ra_password)
        TestProjects.user_ra_id = int(user_ra_id)

        TestProjects.project_src_repo_id, TestProjects.project_src_repo_name = self.project.create_project(
            metadata={"public": "false"}, **TestProjects.USER_RA_CLIENT)

        # Push image test1:1.0, test1:2.0, test1:3.0,latest, test2:1.0, test2:latest, test3:1.0
        push_special_image_to_project(TestProjects.project_src_repo_name,
                                      harbor_server, user_ra_name,
                                      user_ra_password, self.repo_name_1,
                                      ['1.0'])
        push_special_image_to_project(TestProjects.project_src_repo_name,
                                      harbor_server, user_ra_name,
                                      user_ra_password, self.repo_name_1,
                                      ['2.0'])
        push_special_image_to_project(TestProjects.project_src_repo_name,
                                      harbor_server, user_ra_name,
                                      user_ra_password, self.repo_name_1,
                                      ['3.0', 'latest'])
        push_special_image_to_project(TestProjects.project_src_repo_name,
                                      harbor_server, user_ra_name,
                                      user_ra_password, self.repo_name_2,
                                      ['1.0'])
        push_special_image_to_project(TestProjects.project_src_repo_name,
                                      harbor_server, user_ra_name,
                                      user_ra_password, self.repo_name_2,
                                      ['latest'])
        push_special_image_to_project(TestProjects.project_src_repo_name,
                                      harbor_server, user_ra_name,
                                      user_ra_password, "test3", ['1.0'])
        push_special_image_to_project(TestProjects.project_src_repo_name,
                                      harbor_server, user_ra_name,
                                      user_ra_password, "test4", ['1.0'])

        tag_data_artifact3_image1 = self.artifact.get_reference_info(
            TestProjects.project_src_repo_name, self.repo_name_1, "3.0",
            **TestProjects.USER_RA_CLIENT)

        tag_data_artifact2_image2 = self.artifact.get_reference_info(
            TestProjects.project_src_repo_name, self.repo_name_2, "latest",
            **TestProjects.USER_RA_CLIENT)

        tags = list_image_tags(
            harbor_server,
            TestProjects.project_src_repo_name + "/" + self.repo_name_1,
            user_ra_name, user_ra_password)
        #Delete all 2 tags of "artifact3" in repostory "image1";
        self.artifact.delete_tag(TestProjects.project_src_repo_name,
                                 self.repo_name_1, "3.0", "latest",
                                 **TestProjects.USER_RA_CLIENT)
        self.artifact.delete_tag(TestProjects.project_src_repo_name,
                                 self.repo_name_1, "3.0", "3.0",
                                 **TestProjects.USER_RA_CLIENT)
        tags = list_image_tags(
            harbor_server,
            TestProjects.project_src_repo_name + "/" + self.repo_name_1,
            user_ra_name, user_ra_password)

        resp = self.repo.list_repositories(TestProjects.project_src_repo_name,
                                           **TestProjects.USER_RA_CLIENT)
        self.assertEqual(len(resp), 4)

        # Create Retention Policy
        retention_id = self.retention.create_retention_policy(
            TestProjects.project_src_repo_id,
            selector_repository="**",
            selector_tag="latest*",
            expect_status_code=201,
            **TestProjects.USER_RA_CLIENT)

        # Add rule
        self.retention.update_retention_add_rule(retention_id,
                                                 selector_repository="test3*",
                                                 selector_tag="**",
                                                 expect_status_code=200,
                                                 **TestProjects.USER_RA_CLIENT)

        # Dry run
        self.retention.trigger_retention_policy(retention_id,
                                                dry_run=True,
                                                **TestProjects.USER_RA_CLIENT)
        time.sleep(10)
        resp = self.retention.get_retention_executions(
            retention_id, **TestProjects.USER_RA_CLIENT)
        self.assertTrue(len(resp) > 0)
        execution = resp[0]
        resp = self.retention.get_retention_exec_tasks(
            retention_id, execution.id, **TestProjects.USER_RA_CLIENT)
        self.assertEqual(len(resp), 4)
        resp = self.retention.get_retention_exec_task_log(
            retention_id, execution.id, resp[0].id,
            **TestProjects.USER_RA_CLIENT)
        #For Debug:
        print("Task 0 log begin:-----------------------------")
        i = 0
        for line in resp.split("\n"):
            print("Line" + str(i) + ": " + line)
            i = i + 1
        print("Task 0 log end:-----------------------------")

        # Real run
        self.retention.trigger_retention_policy(retention_id,
                                                dry_run=False,
                                                **TestProjects.USER_RA_CLIENT)
        time.sleep(10)
        resp = self.retention.get_retention_executions(
            retention_id, **TestProjects.USER_RA_CLIENT)
        self.assertTrue(len(resp) > 1)
        execution = resp[0]
        resp = self.retention.get_retention_exec_tasks(
            retention_id, execution.id, **TestProjects.USER_RA_CLIENT)
        self.assertEqual(len(resp), 4)
        resp = self.retention.get_retention_exec_task_log(
            retention_id, execution.id, resp[0].id,
            **TestProjects.USER_RA_CLIENT)
        print(resp)

        #List artifacts successfully, and untagged artifact in test1 should be the only one retained;
        artifacts_1 = self.artifact.list_artifacts(
            TestProjects.project_src_repo_name, self.repo_name_1,
            **TestProjects.USER_RA_CLIENT)
        self.assertTrue(len(artifacts_1) == 1)
        self.assertEqual(artifacts_1[0].digest,
                         tag_data_artifact3_image1.digest)

        #List artifacts successfully, and artifact with latest tag in test2 should be the only one retained;
        artifacts_2 = self.artifact.list_artifacts(
            TestProjects.project_src_repo_name, self.repo_name_2,
            **TestProjects.USER_RA_CLIENT)
        self.assertTrue(len(artifacts_2) == 1)
        self.assertEqual(artifacts_2[0].digest,
                         tag_data_artifact2_image2.digest)
Beispiel #2
0
class TestProjects(unittest.TestCase):
    @suppress_urllib3_warning
    def setUp(self):
        self.project= Project()
        self.user= User()
        self.artifact = Artifact()
        self.repo= Repository()
        self.url = ADMIN_CLIENT["endpoint"]
        self.user_password = "******"
        self.repo_name = "hello-world"

    @unittest.skipIf(TEARDOWN == False, "Test data won't be erased.")
    def tearDown(self):
        #1. Delete repository(RA,IA) by user(UA);
        self.repo.delete_repoitory(TestProjects.project_name, self.repo_name, **TestProjects.USER_CLIENT)

        #2. Delete project(PA);
        self.project.delete_project(TestProjects.project_id, **TestProjects.USER_CLIENT)

        #3. Delete user(UA).
        self.user.delete_user(TestProjects.user_id, **ADMIN_CLIENT)
        print("Case completed")

    def testCreateDeleteTag(self):
        """
        Test case:
            Create/Delete tag
        Test step and expected result:
            1. Create a new user(UA);
            2. Create a new project(PA) by user(UA);
            3. Push an image(IA) to Harbor by docker successfully;
            4. Create a tag(1.0) for the image(IA);
            5. Get the image(latest) from Harbor successfully;
            6. Verify the image(IA) contains tag named 1.0;
            7. Delete the tag(1.0) from image(IA);
            8. Get the image(IA) from Harbor successfully;
            9. Verify the image(IA) contains no tag named 1.0;
        Tear down:
            1. Delete repository(RA,IA) by user(UA);
            2. Delete project(PA);
            3. Delete user(UA).
        """
        #1. Create a new user(UA);
        TestProjects.user_id, user_name = self.user.create_user(user_password = self.user_password, **ADMIN_CLIENT)

        TestProjects.USER_CLIENT=dict(with_tag = True, endpoint = self.url, username = user_name, password = self.user_password)

        #2. Create a new project(PA) by user(UA);
        TestProjects.project_id, TestProjects.project_name = self.project.create_project(metadata = {"public": "false"}, **TestProjects.USER_CLIENT)

        #3. Push an image(IA) to Harbor by docker successfully;
        repo_name, tag = push_self_build_image_to_project(TestProjects.project_name, harbor_server, 'admin', 'Harbor12345', self.repo_name, "latest")

        #4. Create a tag(1.0) for the image(IA)
        self.artifact.create_tag(TestProjects.project_name, self.repo_name, tag, "1.0",**TestProjects.USER_CLIENT)

        #5. Get the image(IA) from Harbor successfully;
        artifact = self.artifact.get_reference_info(TestProjects.project_name, self.repo_name, tag, **TestProjects.USER_CLIENT)

        #6. Verify the image(IA) contains tag named 1.0;
        self.assertEqual(artifact.tags[0].name, "1.0")
        self.assertEqual(artifact.tags[1].name, tag)

        #7. Delete the tag(1.0) from image(IA);
        self.artifact.delete_tag(TestProjects.project_name, self.repo_name, tag, "1.0",**TestProjects.USER_CLIENT)

        #8. Get the image(latest) from Harbor successfully;
        artifact = self.artifact.get_reference_info(TestProjects.project_name, self.repo_name, tag, **TestProjects.USER_CLIENT)

        #9. Verify the image(IA) contains no tag named 1.0;
        self.assertEqual(artifact.tags[0].name, tag)
Beispiel #3
0
class TestRobotAccount(unittest.TestCase):
    @suppress_urllib3_warning
    def setUp(self):
        self.project = Project()
        self.user = User()
        self.repo = Repository()
        self.artifact = Artifact()
        self.robot = Robot()
        self.scan = Scan()
        self.label = Label()
        self.chart = Chart()

        TestRobotAccount.url = ADMIN_CLIENT["endpoint"]
        TestRobotAccount.user_ra_password = "******"
        print("setup")

    @unittest.skipIf(TEARDOWN == True, "Test data won't be erased.")
    def do_01_tearDown(self):
        #1. Delete repository(RA) by user(UA);
        self.repo.delete_repoitory(self.project_ra_name_a,
                                   self.repo_name_in_project_a.split('/')[1],
                                   **self.USER_RA_CLIENT)
        self.repo.delete_repoitory(self.project_ra_name_b,
                                   self.repo_name_in_project_b.split('/')[1],
                                   **self.USER_RA_CLIENT)
        self.repo.delete_repoitory(self.project_ra_name_c,
                                   self.repo_name_in_project_c.split('/')[1],
                                   **self.USER_RA_CLIENT)
        self.repo.delete_repoitory(self.project_ra_name_a,
                                   self.repo_name_pa.split('/')[1],
                                   **self.USER_RA_CLIENT)

        #2. Delete project(PA);
        self.project.delete_project(self.project_ra_id_a,
                                    **self.USER_RA_CLIENT)
        self.project.delete_project(self.project_ra_id_b,
                                    **self.USER_RA_CLIENT)
        self.project.delete_project(self.project_ra_id_c,
                                    **self.USER_RA_CLIENT)

        #3. Delete user(UA).
        self.user.delete_user(self.user_ra_id, **ADMIN_CLIENT)

    def test_01_ProjectlevelRobotAccount(self):
        """
        Test case:
            Robot Account
        Test step and expected result:
			1. Create user(UA);
			2. Create private project(PA), private project(PB) and public project(PC) by user(UA);
			3. Push image(ImagePA) to project(PA), image(ImagePB) to project(PB) and image(ImagePC) to project(PC) by user(UA);
			4. Create a new robot account(RA) with pull and push privilige in project(PA) by user(UA);
			5. Check robot account info, it should has both pull and push priviliges;
			6. Pull image(ImagePA) from project(PA) by robot account(RA), it must be successful;
			7. Push image(ImageRA) to project(PA) by robot account(RA), it must be successful;
			8. Push image(ImageRA) to project(PB) by robot account(RA), it must be not successful;
			9. Pull image(ImagePB) from project(PB) by robot account(RA), it must be not successful;
			10. Pull image from project(PC), it must be successful;
			11. Push image(ImageRA) to project(PC) by robot account(RA), it must be not successful;
			12. Update action property of robot account(RA);
			13. Pull image(ImagePA) from project(PA) by robot account(RA), it must be not successful;
			14. Push image(ImageRA) to project(PA) by robot account(RA), it must be not successful;
			15. Delete robot account(RA), it must be not successful.
        Tear down:
            1. Delete repository(RA) by user(UA);
            2. Delete project(PA);
            3. Delete user(UA).
        """
        image_project_a = "haproxy"
        image_project_b = "hello-world"
        image_project_c = "httpd"
        image_robot_account = "alpine"
        tag = "latest"

        #1. Create user(UA);"
        self.user_ra_id, user_ra_name = self.user.create_user(
            user_password=TestRobotAccount.user_ra_password, **ADMIN_CLIENT)
        self.USER_RA_CLIENT = dict(endpoint=TestRobotAccount.url,
                                   username=user_ra_name,
                                   password=TestRobotAccount.user_ra_password)

        #2. Create private project(PA), private project(PB) and public project(PC) by user(UA);
        self.project_ra_id_a, self.project_ra_name_a = self.project.create_project(
            metadata={"public": "false"}, **self.USER_RA_CLIENT)
        self.project_ra_id_b, self.project_ra_name_b = self.project.create_project(
            metadata={"public": "false"}, **self.USER_RA_CLIENT)
        self.project_ra_id_c, self.project_ra_name_c = self.project.create_project(
            metadata={"public": "true"}, **self.USER_RA_CLIENT)

        #3. Push image(ImagePA) to project(PA), image(ImagePB) to project(PB) and image(ImagePC) to project(PC) by user(UA);
        self.repo_name_in_project_a, tag_a = push_self_build_image_to_project(
            self.project_ra_name_a, harbor_server, user_ra_name,
            TestRobotAccount.user_ra_password, image_project_a, tag)
        self.repo_name_in_project_b, tag_b = push_self_build_image_to_project(
            self.project_ra_name_b, harbor_server, user_ra_name,
            TestRobotAccount.user_ra_password, image_project_b, tag)
        self.repo_name_in_project_c, tag_c = push_self_build_image_to_project(
            self.project_ra_name_c, harbor_server, user_ra_name,
            TestRobotAccount.user_ra_password, image_project_c, tag)

        #4. Create a new robot account(RA) with pull and push privilege in project(PA) by user(UA);
        robot_id, robot_account = self.robot.create_project_robot(
            self.project_ra_name_a, 30, **self.USER_RA_CLIENT)

        #5. Check robot account info, it should has both pull and push privilege;
        data = self.robot.get_robot_account_by_id(robot_id,
                                                  **self.USER_RA_CLIENT)
        _assert_status_code(robot_account.name, data.name)

        #6. Pull image(ImagePA) from project(PA) by robot account(RA), it must be successful;
        pull_harbor_image(harbor_server, robot_account.name,
                          robot_account.secret, self.repo_name_in_project_a,
                          tag_a)

        #7. Push image(ImageRA) to project(PA) by robot account(RA), it must be successful;
        self.repo_name_pa, _ = push_self_build_image_to_project(
            self.project_ra_name_a, harbor_server, robot_account.name,
            robot_account.secret, image_robot_account, tag)

        #8. Push image(ImageRA) to project(PB) by robot account(RA), it must be not successful;
        push_self_build_image_to_project(
            self.project_ra_name_b,
            harbor_server,
            robot_account.name,
            robot_account.secret,
            image_robot_account,
            tag,
            expected_error_message="unauthorized to access repository")

        #9. Pull image(ImagePB) from project(PB) by robot account(RA), it must be not successful;
        pull_harbor_image(
            harbor_server,
            robot_account.name,
            robot_account.secret,
            self.repo_name_in_project_b,
            tag_b,
            expected_error_message="unauthorized to access repository")

        #10. Pull image from project(PC), it must be successful;
        pull_harbor_image(harbor_server, robot_account.name,
                          robot_account.secret, self.repo_name_in_project_c,
                          tag_c)

        #11. Push image(ImageRA) to project(PC) by robot account(RA), it must be not successful;
        push_self_build_image_to_project(
            self.project_ra_name_c,
            harbor_server,
            robot_account.name,
            robot_account.secret,
            image_robot_account,
            tag,
            expected_error_message="unauthorized to access repository")

        #12. Update action property of robot account(RA);"
        self.robot.disable_robot_account(robot_id, True, **self.USER_RA_CLIENT)

        #13. Pull image(ImagePA) from project(PA) by robot account(RA), it must be not successful;
        pull_harbor_image(
            harbor_server,
            robot_account.name,
            robot_account.secret,
            self.repo_name_in_project_a,
            tag_a,
            expected_login_error_message="unauthorized: authentication required"
        )

        #14. Push image(ImageRA) to project(PA) by robot account(RA), it must be not successful;
        push_self_build_image_to_project(
            self.project_ra_name_a,
            harbor_server,
            robot_account.name,
            robot_account.secret,
            image_robot_account,
            tag,
            expected_login_error_message="unauthorized: authentication required"
        )

        #15. Delete robot account(RA), it must be not successful.
        self.robot.delete_robot_account(robot_id, **self.USER_RA_CLIENT)

        self.do_01_tearDown()

    def verify_repository_pushable(self, project_access_list,
                                   system_ra_client):
        for project_access in project_access_list:
            print(r"project_access:", project_access)
            if project_access["check_list"][1]:  #---repository:push---
                repo = push_self_build_image_to_project(
                    project_access["project_name"], harbor_server,
                    system_ra_client["username"], system_ra_client["password"],
                    "test_pushable" + base._random_name("repo"),
                    "v6.8.1" + base._random_name("tag"))
            else:
                push_self_build_image_to_project(
                    project_access["project_name"],
                    harbor_server,
                    system_ra_client["username"],
                    system_ra_client["password"],
                    "test_unpushable" + base._random_name("repo"),
                    "v6.8.1" + base._random_name("tag"),
                    expected_error_message="unauthorized to access repository")

    def verify_repository_unpushable(
            self,
            project_access_list,
            system_ra_client,
            expected_login_error_message="unauthorized: authentication required"
    ):
        for project_access in project_access_list:  #---repository:push---
            push_self_build_image_to_project(
                project_access["project_name"],
                harbor_server,
                system_ra_client["username"],
                system_ra_client["password"],
                "test_unpushable" + base._random_name("repo"),
                "v6.8.1" + base._random_name("tag"),
                expected_login_error_message=expected_login_error_message)

    def test_02_SystemlevelRobotAccount(self):
        """
        Test case:
            Robot Account
        Test step and expected result:
			1. Define a number of access lists;
            2. Create the same number of private projects;
			3. Create a system robot account has permission for those projects;
            4. Verify the system robot account has the corresponding rights;
			5. Disable the system robot account;
            6. Verify the system robot account has no the corresponding rights;
			7. Enable the system robot account;
            8. Verify the system robot account has the corresponding rights;
			9. Refresh secret for the system robot account;
            10. Verify the system robot account has no the corresponding right with the old secret already;
            11. Verify the system robot account still has the corresponding right with the new secret;
			12. List system robot account, then add a new project to the system robot account project permission list;
            13. Delete this project;
            14. List system robot account successfully;
			15. Delete the system robot account;
            16. Verify the system robot account has no the corresponding right;
            17. Add a system robot account with all project coverd;
            18. Verify the system robot account has no the corresponding right;
        """
        #1. Define a number of access lists;
        CHART_FILE_LIST = [
            dict(name='prometheus', version='7.0.2'),
            dict(name='harbor', version='0.2.0')
        ]
        for i in range(2):
            base.run_command([
                "curl", r"-o", "./tests/apitests/python/{}-{}.tgz".format(
                    CHART_FILE_LIST[i]["name"], CHART_FILE_LIST[i]["version"]),
                "https://storage.googleapis.com/harbor-builds/helm-chart-test-files/{}-{}.tgz"
                .format(CHART_FILE_LIST[i]["name"],
                        CHART_FILE_LIST[i]["version"])
            ])

        #Make sure that whether 'True' or 'False' must be included in each line or row.
        check_list = [
            [True, True, True, True, True, True, False, True, False, True],
            [False, False, False, False, True, True, False, True, True, False],
            [True, False, True, False, True, False, True, False, True, True],
            [False, False, False, True, False, True, False, True, True, False]
        ]
        access_list_list = []
        for i in range(len(check_list)):
            access_list_list.append(
                self.robot.create_access_list(check_list[i]))

        #2. Create the same number of private projects;
        robot_account_Permissions_list = []
        project_access_list = []
        for i in range(len(check_list)):
            with created_user(TestRobotAccount.user_ra_password,
                              _teardown=False) as (user_id, username):
                with created_project(metadata={"public": "false"},
                                     user_id=user_id,
                                     _teardown=False) as (project_id,
                                                          project_name):
                    project_access_list.append(
                        dict(project_name=project_name,
                             project_id=project_id,
                             check_list=check_list[i]))
                    robot_account_Permissions = v2_swagger_client.Permission(
                        kind="project",
                        namespace=project_name,
                        access=access_list_list[i])
                    robot_account_Permissions_list.append(
                        robot_account_Permissions)

        #3. Create a system robot account has permission for those projects;
        system_robot_account_id, system_robot_account = self.robot.create_system_robot(
            robot_account_Permissions_list, 300)
        print("system_robot_account:", system_robot_account)
        SYSTEM_RA_CLIENT = dict(endpoint=TestRobotAccount.url,
                                username=system_robot_account.name,
                                password=system_robot_account.secret)
        SYSTEM_RA_CHART_CLIENT = dict(endpoint=CHART_API_CLIENT["endpoint"],
                                      username=SYSTEM_RA_CLIENT["username"],
                                      password=SYSTEM_RA_CLIENT["password"])

        #4. Verify the system robot account has the corresponding rights;
        for project_access in project_access_list:
            print(r"project_access:", project_access)
            if project_access["check_list"][1]:  #---repository:push---
                repo = push_self_build_image_to_project(
                    project_access["project_name"], harbor_server,
                    SYSTEM_RA_CLIENT["username"], SYSTEM_RA_CLIENT["password"],
                    "test_pushable", "v6.8.1")
            else:
                push_self_build_image_to_project(
                    project_access["project_name"],
                    harbor_server,
                    SYSTEM_RA_CLIENT["username"],
                    SYSTEM_RA_CLIENT["password"],
                    "test_unpushable",
                    "v6.8.1",
                    expected_error_message="unauthorized to access repository")

            tag_for_del = "v1.0.0"
            repo_name, tag = push_self_build_image_to_project(
                project_access["project_name"], harbor_server,
                ADMIN_CLIENT["username"], ADMIN_CLIENT["password"],
                "test_del_artifact", tag_for_del)
            if project_access["check_list"][0]:  #---repository:pull---
                pull_harbor_image(harbor_server, SYSTEM_RA_CLIENT["username"],
                                  SYSTEM_RA_CLIENT["password"], repo_name,
                                  tag_for_del)
            else:
                pull_harbor_image(
                    harbor_server,
                    SYSTEM_RA_CLIENT["username"],
                    SYSTEM_RA_CLIENT["password"],
                    repo_name,
                    tag_for_del,
                    expected_error_message=
                    "action: pull: unauthorized to access repository")

            if project_access["check_list"][2]:  #---artifact:delete---
                self.artifact.delete_artifact(project_access["project_name"],
                                              repo_name.split('/')[1],
                                              tag_for_del, **SYSTEM_RA_CLIENT)
            else:
                self.artifact.delete_artifact(project_access["project_name"],
                                              repo_name.split('/')[1],
                                              tag_for_del,
                                              expect_status_code=403,
                                              **SYSTEM_RA_CLIENT)

            #Prepare for chart read and delete
            self.chart.upload_chart(
                project_access["project_name"],
                r'./tests/apitests/python/{}-{}.tgz'.format(
                    CHART_FILE_LIST[1]["name"],
                    CHART_FILE_LIST[1]["version"]), **CHART_API_CLIENT)
            if project_access["check_list"][3]:  #---helm-chart:read---
                library.helm.helm2_fetch_chart_file(
                    "chart_repo_" + base._random_name("repo"), harbor_url,
                    project_access["project_name"],
                    SYSTEM_RA_CLIENT["username"], SYSTEM_RA_CLIENT["password"],
                    CHART_FILE_LIST[1]["name"])
            else:
                library.helm.helm2_fetch_chart_file(
                    "chart_repo_" + base._random_name("repo"),
                    harbor_url,
                    project_access["project_name"],
                    SYSTEM_RA_CLIENT["username"],
                    SYSTEM_RA_CLIENT["password"],
                    CHART_FILE_LIST[1]["name"],
                    expected_add_repo_error_message="403 Forbidden")

            if project_access["check_list"][
                    4]:  #---helm-chart-version:create---
                self.chart.upload_chart(
                    project_access["project_name"],
                    r'./tests/apitests/python/{}-{}.tgz'.format(
                        CHART_FILE_LIST[0]["name"],
                        CHART_FILE_LIST[0]["version"]),
                    **SYSTEM_RA_CHART_CLIENT)
            else:
                self.chart.upload_chart(
                    project_access["project_name"],
                    r'./tests/apitests/python/{}-{}.tgz'.format(
                        CHART_FILE_LIST[0]["name"],
                        CHART_FILE_LIST[0]["version"]),
                    expect_status_code=403,
                    **SYSTEM_RA_CHART_CLIENT)

            if project_access["check_list"][
                    5]:  #---helm-chart-version:delete---
                self.chart.delete_chart_with_version(
                    project_access["project_name"], CHART_FILE_LIST[1]["name"],
                    CHART_FILE_LIST[1]["version"], **SYSTEM_RA_CHART_CLIENT)
            else:
                self.chart.delete_chart_with_version(
                    project_access["project_name"],
                    CHART_FILE_LIST[1]["name"],
                    CHART_FILE_LIST[1]["version"],
                    expect_status_code=403,
                    **SYSTEM_RA_CHART_CLIENT)

            repo_name, tag = push_self_build_image_to_project(
                project_access["project_name"], harbor_server,
                ADMIN_CLIENT["username"], ADMIN_CLIENT["password"],
                "test_create_tag", "latest_1")
            self.artifact.create_tag(project_access["project_name"],
                                     repo_name.split('/')[1], tag,
                                     "for_delete", **ADMIN_CLIENT)
            if project_access["check_list"][6]:  #---tag:create---
                self.artifact.create_tag(project_access["project_name"],
                                         repo_name.split('/')[1], tag, "1.0",
                                         **SYSTEM_RA_CLIENT)
            else:
                self.artifact.create_tag(project_access["project_name"],
                                         repo_name.split('/')[1],
                                         tag,
                                         "1.0",
                                         expect_status_code=403,
                                         **SYSTEM_RA_CLIENT)

            if project_access["check_list"][7]:  #---tag:delete---
                self.artifact.delete_tag(project_access["project_name"],
                                         repo_name.split('/')[1], tag,
                                         "for_delete", **SYSTEM_RA_CLIENT)
            else:
                self.artifact.delete_tag(project_access["project_name"],
                                         repo_name.split('/')[1],
                                         tag,
                                         "for_delete",
                                         expect_status_code=403,
                                         **SYSTEM_RA_CLIENT)

            repo_name, tag = push_self_build_image_to_project(
                project_access["project_name"], harbor_server,
                ADMIN_CLIENT["username"], ADMIN_CLIENT["password"],
                "test_create_artifact_label", "latest_1")
            #Add project level label to artifact
            label_id, _ = self.label.create_label(
                project_id=project_access["project_id"],
                scope="p",
                **ADMIN_CLIENT)
            if project_access["check_list"][8]:  #---artifact-label:create---
                self.artifact.add_label_to_reference(
                    project_access["project_name"],
                    repo_name.split('/')[1], tag, int(label_id),
                    **SYSTEM_RA_CLIENT)
            else:
                self.artifact.add_label_to_reference(
                    project_access["project_name"],
                    repo_name.split('/')[1],
                    tag,
                    int(label_id),
                    expect_status_code=403,
                    **SYSTEM_RA_CLIENT)

            if project_access["check_list"][9]:  #---scan:create---
                self.scan.scan_artifact(project_access["project_name"],
                                        repo_name.split('/')[1], tag,
                                        **SYSTEM_RA_CLIENT)
            else:
                self.scan.scan_artifact(project_access["project_name"],
                                        repo_name.split('/')[1],
                                        tag,
                                        expect_status_code=403,
                                        **SYSTEM_RA_CLIENT)

#5. Disable the system robot account;
        self.robot.update_system_robot_account(system_robot_account_id,
                                               system_robot_account.name,
                                               robot_account_Permissions_list,
                                               disable=True,
                                               **ADMIN_CLIENT)

        #6. Verify the system robot account has no the corresponding rights;
        self.verify_repository_unpushable(project_access_list,
                                          SYSTEM_RA_CLIENT)

        #7. Enable the system robot account;
        self.robot.update_system_robot_account(system_robot_account_id,
                                               system_robot_account.name,
                                               robot_account_Permissions_list,
                                               disable=False,
                                               **ADMIN_CLIENT)

        #8. Verify the system robot account has the corresponding rights;
        self.verify_repository_pushable(project_access_list, SYSTEM_RA_CLIENT)

        #9. Refresh secret for the system robot account;
        new_secret = "new_secret_At_321"
        self.robot.refresh_robot_account_secret(system_robot_account_id,
                                                new_secret, **ADMIN_CLIENT)

        #10. Verify the system robot account has no the corresponding right with the old secret already;
        self.verify_repository_unpushable(project_access_list,
                                          SYSTEM_RA_CLIENT)

        #11. Verify the system robot account still has the corresponding right with the new secret;
        SYSTEM_RA_CLIENT["password"] = new_secret
        self.verify_repository_pushable(project_access_list, SYSTEM_RA_CLIENT)

        #12. List system robot account, then add a new project to the system robot account project permission list;
        self.robot.list_robot(**ADMIN_CLIENT)
        project_for_del_id, project_for_del_name = self.project.create_project(
            metadata={"public": "true"}, **ADMIN_CLIENT)
        robot_account_Permissions = v2_swagger_client.Permission(
            kind="project",
            namespace=project_for_del_name,
            access=access_list_list[0])
        robot_account_Permissions_list.append(robot_account_Permissions)
        self.robot.update_system_robot_account(system_robot_account_id,
                                               system_robot_account.name,
                                               robot_account_Permissions_list,
                                               **ADMIN_CLIENT)
        self.robot.list_robot(**ADMIN_CLIENT)

        #13. Delete this project;
        self.project.delete_project(project_for_del_id, **ADMIN_CLIENT)

        #14. List system robot account successfully;
        self.robot.list_robot(**ADMIN_CLIENT)

        #15. Delete the system robot account;
        self.robot.delete_robot_account(system_robot_account_id,
                                        **ADMIN_CLIENT)

        #16. Verify the system robot account has no the corresponding right;
        self.verify_repository_unpushable(project_access_list,
                                          SYSTEM_RA_CLIENT)

        #17. Add a system robot account with all project coverd;
        all_true_access_list = self.robot.create_access_list([True] * 10)
        robot_account_Permissions_list = []
        robot_account_Permissions = v2_swagger_client.Permission(
            kind="project", namespace="*", access=all_true_access_list)
        robot_account_Permissions_list.append(robot_account_Permissions)
        _, system_robot_account_cover_all = self.robot.create_system_robot(
            robot_account_Permissions_list, 300)

        #18. Verify the system robot account has no the corresponding right;
        print("system_robot_account_cover_all:",
              system_robot_account_cover_all)
        SYSTEM_RA_CLIENT_COVER_ALL = dict(
            endpoint=TestRobotAccount.url,
            username=system_robot_account_cover_all.name,
            password=system_robot_account_cover_all.secret)
        projects = self.project.get_projects(dict(), **ADMIN_CLIENT)
        print("All projects:", projects)
        project_access_list = []
        for i in range(len(projects)):
            project_access_list.append(
                dict(project_name=projects[i].name,
                     project_id=projects[i].project_id,
                     check_list=all_true_access_list))
        self.verify_repository_pushable(project_access_list,
                                        SYSTEM_RA_CLIENT_COVER_ALL)
class TestTagImmutability(unittest.TestCase):
    @suppress_urllib3_warning
    def setUp(self):
        self.url = ADMIN_CLIENT["endpoint"]
        self.user_password = "******"
        self.project= Project()
        self.user= User()
        self.repo= Repository()
        self.registry = Registry()
        self.artifact = Artifact()
        self.tag_immutability = Tag_Immutability()
        self.project_id, self.project_name, self.user_id, self.user_name = [None] * 4
        self.user_id, self.user_name = self.user.create_user(user_password = self.user_password, **ADMIN_CLIENT)
        self.USER_CLIENT = dict(with_signature = True, with_immutable_status = True, endpoint = self.url, username = self.user_name, password = self.user_password)
        self.exsiting_rule = dict(selector_repository="rel*", selector_tag="v2.*")
        self.project_id, self.project_name = self.project.create_project(metadata = {"public": "false"}, **self.USER_CLIENT)

    @unittest.skipIf(TEARDOWN == False, "Test data won't be erased.")
    def tearDown(self):
        print("Case completed")

    def check_tag_immutability(self, artifact, tag_name, status = True):
        for tag in artifact.tags:
            if tag.name == tag_name:
                self.assertTrue(tag.immutable == status)
                return
        raise Exception("No tag {} found in artifact {}".format(tag, artifact))

    def test_disability_of_rules(self):
        """
        Test case:
            Test Disability Of Rules
        Test step and expected result:
            1. Create a new project;
            2. Push image A to the project with 2 tags A and B;
            3. Create a disabled rule matched image A with tag A;
            4. Both tags of image A should not be immutable;
            5. Enable this rule;
            6. image A with tag A should be immutable.
        """
        image_a = dict(name="image_disability_a", tag1="latest", tag2="6.2.2")

        #1. Create a new project;
        project_id, project_name = self.project.create_project(metadata = {"public": "false"}, **self.USER_CLIENT)

        #2. Push image A to the project with 2 tags;
        push_special_image_to_project(project_name, harbor_server, self.user_name, self.user_password, image_a["name"], [image_a["tag1"], image_a["tag2"]])

        #3. Create a disabled rule matched image A;
        rule_id = self.tag_immutability.create_rule(project_id, disabled = True, selector_repository=image_a["name"], selector_tag=str(image_a["tag1"])[0:2] + "*", **self.USER_CLIENT)

        #4. Both tags of image A should not be immutable;
        artifact_a = self.artifact.get_reference_info(project_name, image_a["name"], image_a["tag2"], **self.USER_CLIENT)
        print("[test_disability_of_rules] - artifact:{}".format(artifact_a))
        self.assertTrue(artifact_a)
        self.check_tag_immutability(artifact_a, image_a["tag1"], status = False)
        self.check_tag_immutability(artifact_a, image_a["tag2"], status = False)

        #5. Enable this rule;
        self.tag_immutability.update_tag_immutability_policy_rule(project_id, rule_id, disabled = False, **self.USER_CLIENT)

        #6. image A with tag A should be immutable.
        artifact_a = self.artifact.get_reference_info(project_name, image_a["name"], image_a["tag2"], **self.USER_CLIENT)
        print("[test_disability_of_rules] - artifact:{}".format(artifact_a))
        self.assertTrue(artifact_a)
        self.check_tag_immutability(artifact_a, image_a["tag1"], status = True)
        self.check_tag_immutability(artifact_a, image_a["tag2"], status = False)

    def test_artifact_and_repo_is_undeletable(self):
        """
        Test case:
            Test Artifact And Repo is Undeleteable
        Test step and expected result:
            1. Create a new project;
            2. Push image A to the project with 2 tags A and B;
            3. Create a enabled rule matched image A with tag A;
            4. Tag A should be immutable;
            5. Artifact is undeletable;
            6. Repository is undeletable.
        """
        image_a = dict(name="image_repo_undeletable_a", tag1="latest", tag2="1.3.2")

        #1. Create a new project;
        project_id, project_name = self.project.create_project(metadata = {"public": "false"}, **self.USER_CLIENT)

        #2. Push image A to the project with 2 tags A and B;
        push_special_image_to_project(project_name, harbor_server, self.user_name, self.user_password, image_a["name"], [image_a["tag1"], image_a["tag2"]])

        #3. Create a enabled rule matched image A with tag A;
        self.tag_immutability.create_rule(project_id, selector_repository=image_a["name"], selector_tag=str(image_a["tag1"])[0:2] + "*", **self.USER_CLIENT)

        #4. Tag A should be immutable;
        artifact_a = self.artifact.get_reference_info(project_name, image_a["name"], image_a["tag2"], **self.USER_CLIENT)
        print("[test_artifact_and_repo_is_undeletable] - artifact:{}".format(artifact_a))
        self.assertTrue(artifact_a)
        self.check_tag_immutability(artifact_a, image_a["tag1"], status = True)
        self.check_tag_immutability(artifact_a, image_a["tag2"], status = False)

        #5. Artifact is undeletable;
        self.artifact.delete_artifact(project_name, image_a["name"], image_a["tag1"], expect_status_code = 412,expect_response_body = "configured as immutable, cannot be deleted", **self.USER_CLIENT)

        #6. Repository is undeletable.
        self.repo.delete_repository(project_name, image_a["name"], expect_status_code = 412, expect_response_body = "configured as immutable, cannot be deleted", **self.USER_CLIENT)

    def test_tag_is_undeletable(self):
        """
        Test case:
            Test Tag is Undeleteable
        Test step and expected result:
            1. Push image A to the project with 2 tags A and B;
            2. Create a enabled rule matched image A with tag A;
            3. Tag A should be immutable;
            4. Tag A is undeletable;
            5. Tag B is deletable.
        """
        image_a = dict(name="image_undeletable_a", tag1="latest", tag2="9.3.2")

        #1. Push image A to the project with 2 tags A and B;
        push_special_image_to_project(self.project_name, harbor_server, self.user_name, self.user_password, image_a["name"], [image_a["tag1"], image_a["tag2"]])

        #2. Create a enabled rule matched image A with tag A;
        self.tag_immutability.create_rule(self.project_id, selector_repository=image_a["name"], selector_tag=str(image_a["tag2"])[0:2] + "*", **self.USER_CLIENT)

        #3. Tag A should be immutable;
        artifact_a = self.artifact.get_reference_info(self.project_name, image_a["name"], image_a["tag2"], **self.USER_CLIENT)
        print("[test_tag_is_undeletable] - artifact:{}".format(artifact_a))
        self.assertTrue(artifact_a)
        self.check_tag_immutability(artifact_a, image_a["tag2"], status = True)

        #4. Tag A is undeletable;
        self.artifact.delete_tag(self.project_name, image_a["name"], image_a["tag1"], image_a["tag2"], expect_status_code = 412, **self.USER_CLIENT)

        #5. Tag B is deletable.
        self.artifact.delete_tag(self.project_name, image_a["name"], image_a["tag1"], image_a["tag1"], **self.USER_CLIENT)

    def test_image_is_unpushable(self):
        """
        Test case:
            Test Image is Unpushable
        Test step and expected result:
            1. Create a new project;
            2. Push image A to the project with 2 tags A and B;
            3. Create a enabled rule matched image A with tag A;
            4. Tag A should be immutable;
            5. Can not push image with the same image name and with the same tag name.
        """
        image_a = dict(name="image_unpushable_a", tag1="latest", tag2="1.3.2")

        #1. Create a new project;
        project_id, project_name = self.project.create_project(metadata = {"public": "false"}, **self.USER_CLIENT)

        #2. Push image A to the project with 2 tags A and B;
        push_special_image_to_project(project_name, harbor_server, self.user_name, self.user_password, image_a["name"], [image_a["tag1"], image_a["tag2"]])

        #3. Create a enabled rule matched image A with tag A;
        self.tag_immutability.create_rule(project_id, selector_repository=image_a["name"], selector_tag=str(image_a["tag1"])[0:2] + "*", **self.USER_CLIENT)

        #4. Tag A should be immutable;
        artifact_a = self.artifact.get_reference_info(project_name, image_a["name"], image_a["tag2"], **self.USER_CLIENT)
        print("[test_image_is_unpushable] - artifact:{}".format(artifact_a))
        self.assertTrue(artifact_a)
        self.check_tag_immutability(artifact_a, image_a["tag1"], status = True)
        self.check_tag_immutability(artifact_a, image_a["tag2"], status = False)

        #5. Can not push image with the same image name and with the same tag name.
        push_special_image_to_project(project_name, harbor_server, self.user_name, self.user_password, image_a["name"], [image_a["tag1"]], size=10
                                      , expected_error_message = "configured as immutable")

    def test_copy_disability(self):
        """
        Test case:
            Test Copy Disability
        Test step and expected result:
            1. Create 2 projects;
            2. Push image A with tag A and B to project A, push image B which has the same image name and tag name to project B;
            3. Create a enabled rule matched image A with tag A;
            4. Tag A should be immutable;
            5. Can not copy artifact from project A to project B with the same repository name.
        """
        image_a = dict(name="image_copy_disability_a", tag1="latest", tag2="1.3.2")

        #1. Create 2 projects;
        project_id, project_name = self.project.create_project(metadata = {"public": "false"}, **self.USER_CLIENT)
        _, project_name_src = self.project.create_project(metadata = {"public": "false"}, **self.USER_CLIENT)

        #2. Push image A with tag A and B to project A, push image B which has the same image name and tag name to project B;
        push_special_image_to_project(project_name, harbor_server, self.user_name, self.user_password, image_a["name"], [image_a["tag1"], image_a["tag2"]])
        push_special_image_to_project(project_name_src, harbor_server, self.user_name, self.user_password, image_a["name"], [image_a["tag1"], image_a["tag2"]])

        #3. Create a enabled rule matched image A with tag A;
        self.tag_immutability.create_rule(project_id, selector_repository=image_a["name"], selector_tag=str(image_a["tag1"])[0:2] + "*", **self.USER_CLIENT)

        #4. Tag A should be immutable;
        artifact_a = self.artifact.get_reference_info(project_name, image_a["name"], image_a["tag2"], **self.USER_CLIENT)
        print("[test_copy_disability] - artifact:{}".format(artifact_a))
        self.assertTrue(artifact_a)
        self.check_tag_immutability(artifact_a, image_a["tag1"], status = True)
        self.check_tag_immutability(artifact_a, image_a["tag2"], status = False)

        #5. Can not copy artifact from project A to project B with the same repository name.
        artifact_a_src = self.artifact.get_reference_info(project_name_src, image_a["name"], image_a["tag2"], **self.USER_CLIENT)
        print("[test_copy_disability] - artifact_a_src:{}".format(artifact_a_src))
        self.artifact.copy_artifact(project_name, image_a["name"], project_name_src+"/"+ image_a["name"] + "@" + artifact_a_src.digest, expect_status_code=412, expect_response_body = "configured as immutable, cannot be updated", **self.USER_CLIENT)

    #def test_replication_disability(self):
    #    pass

    def test_priority_of_rules(self):
        """
        Test case:
            Test Priority Of Rules(excluding rule will not affect matching rule)
        Test step and expected result:
            1. Push image A, B and C, image A has only 1 tag named tag1;
            2. Create a matching rule that matches image A and tag named tag2 which is not exist;
            3. Create a excluding rule to exlude image A and B;
            4. Add a tag named tag2 to image A, tag2 should be immutable;
            5. Tag2 should be immutable;
            6. All tags in image B should be immutable;
            7. All tags in image C should not be immutable;
            8. Disable all rules.
        """
        image_a = dict(name="image_priority_a", tag1="latest", tag2="6.3.2")
        image_b = dict(name="image_priority_b", tag1="latest", tag2="0.12.0")
        image_c = dict(name="image_priority_c", tag1="latest", tag2="3.12.0")

        #1. Push image A, B and C, image A has only 1 tag named tag1;
        push_special_image_to_project(self.project_name, harbor_server, self.user_name, self.user_password, image_a["name"], [image_a["tag1"]])
        push_special_image_to_project(self.project_name, harbor_server, self.user_name, self.user_password, image_b["name"], [image_b["tag1"],image_b["tag2"]])
        push_special_image_to_project(self.project_name, harbor_server, self.user_name, self.user_password, image_c["name"], [image_c["tag1"],image_c["tag2"]])

        #2. Create a matching rule that matches image A and tag named tag2 which is not exist;
        rule_id_1 = self.tag_immutability.create_rule(self.project_id, selector_repository=image_a["name"], selector_tag=image_a["tag2"], **self.USER_CLIENT)

        #3. Create a excluding rule to exlude image A and B;
        rule_id_2 = self.tag_immutability.create_rule(self.project_id, selector_repository_decoration = "repoExcludes",
                                          selector_repository="{image_priority_a,image_priority_b}", selector_tag="**", **self.USER_CLIENT)

        #4. Add a tag named tag2 to image A, tag2 should be immutable;
        self.artifact.create_tag(self.project_name, image_a["name"], image_a["tag1"], image_a["tag2"], **self.USER_CLIENT)

        #5. Tag2 should be immutable;
        artifact_a = self.artifact.get_reference_info(self.project_name, image_a["name"], image_a["tag2"], **self.USER_CLIENT)
        print("[test_priority_of_rules] - artifact:{}".format(artifact_a))
        self.assertTrue(artifact_a)
        self.check_tag_immutability(artifact_a, image_a["tag2"], status = True)
        self.check_tag_immutability(artifact_a, image_a["tag1"], status = False)

        #6. All tags in image B should be immutable;
        artifact_b = self.artifact.get_reference_info(self.project_name, image_b["name"], image_b["tag2"], **self.USER_CLIENT)
        print("[test_priority_of_rules] - artifact:{}".format(artifact_b))
        self.assertTrue(artifact_b)
        self.check_tag_immutability(artifact_b, image_b["tag2"], status = False)
        self.check_tag_immutability(artifact_b, image_b["tag1"], status = False)

        #7. All tags in image C should not be immutable;
        artifact_c = self.artifact.get_reference_info(self.project_name, image_c["name"], image_c["tag2"], **self.USER_CLIENT)
        print("[test_priority_of_rules] - artifact:{}".format(artifact_c))
        self.assertTrue(artifact_c)
        self.check_tag_immutability(artifact_c, image_c["tag2"], status = True)
        self.check_tag_immutability(artifact_c, image_c["tag1"], status = True)

        #8. Disable all rules.
        self.tag_immutability.update_tag_immutability_policy_rule(self.project_id, rule_id_1, disabled = True, **self.USER_CLIENT)
        self.tag_immutability.update_tag_immutability_policy_rule(self.project_id, rule_id_2, disabled = True, **self.USER_CLIENT)

    def test_add_exsiting_rule(self):
        """
        Test case:
            Test Priority Of Rules(excluding rule will not affect matching rule)
        Test step and expected result:
            1. Push image A and B with no tag;
            2. Create a immutability policy rule A;
            3. Fail to create rule B which has the same config as rule A;
        """
        self.tag_immutability.create_tag_immutability_policy_rule(self.project_id, **self.exsiting_rule, **self.USER_CLIENT)
        self.tag_immutability.create_tag_immutability_policy_rule(self.project_id, **self.exsiting_rule, expect_status_code = 409, **self.USER_CLIENT)
class TestProjects(unittest.TestCase):
    @classmethod
    def setUp(self):
        self.system = System()
        self.project = Project()
        self.user = User()
        self.repo = Repository()
        self.artifact = Artifact()
        self.repo_name = "test_repo"
        self.repo_name_untag = "test_untag"
        self.tag = "v1.0"

    @classmethod
    def tearDown(self):
        print("Case completed")

    @unittest.skipIf(TEARDOWN == True, "Test data won't be erased.")
    def test_ClearData(self):
        #2. Delete project(PA);
        self.project.delete_project(TestProjects.project_gc_id, **TestProjects.USER_GC_CLIENT)

        #3. Delete user(UA);
        self.user.delete_user(TestProjects.user_gc_id, **ADMIN_CLIENT)

    def testGarbageCollection(self):
        """
        Test case:
            Garbage Collection
        Test step and expected result:
            1. Create a new user(UA);
            2. Create project(PA) and project(PB) by user(UA);
            3. Push a image in project(PA) and then delete repository by admin;
            4. Get repository by user(UA), it should get nothing;
            5. Tigger garbage collection operation;
            6. Check garbage collection job was finished;
            7. Get garbage collection log, check there is a number of files was deleted;
            8. Push a image in project(PB) by admin and delete the only tag;
            9. Tigger garbage collection operation;
            10. Check garbage collection job was finished;
            11. Repository with untag image should be still there;
            12. But no any artifact in repository anymore.
        Tear down:
            1. Delete project(PA);
            2. Delete user(UA).
        """
        url = ADMIN_CLIENT["endpoint"]
        admin_name = ADMIN_CLIENT["username"]
        admin_password = ADMIN_CLIENT["password"]
        user_gc_password = "******"

        #1. Create a new user(UA);
        TestProjects.user_gc_id, user_gc_name = self.user.create_user(user_password = user_gc_password, **ADMIN_CLIENT)

        TestProjects.USER_GC_CLIENT=dict(endpoint = url, username = user_gc_name, password = user_gc_password)

        #2. Create project(PA) and project(PB) by user(UA);
        TestProjects.project_gc_id, TestProjects.project_gc_name = self.project.create_project(metadata = {"public": "false"}, **TestProjects.USER_GC_CLIENT)
        TestProjects.project_gc_untag_id, TestProjects.project_gc_untag_name = self.project.create_project(metadata = {"public": "false"}, **TestProjects.USER_GC_CLIENT)

        #3. Push a image in project(PA) and then delete repository by admin;
        push_special_image_to_project(TestProjects.project_gc_name, harbor_server, admin_name, admin_password, self.repo_name, ["latest", "v1.2.3"])
        self.repo.delete_repoitory(TestProjects.project_gc_name, self.repo_name, **TestProjects.USER_GC_CLIENT)

        #4. Get repository by user(UA), it should get nothing;
        repo_data = self.repo.list_repositories(TestProjects.project_gc_name, **TestProjects.USER_GC_CLIENT)
        _assert_status_code(len(repo_data), 0)

        #8. Push a image in project(PB) by admin and delete the only tag;
        push_special_image_to_project(TestProjects.project_gc_untag_name, harbor_server, admin_name, admin_password, self.repo_name_untag, [self.tag])
        self.artifact.delete_tag(TestProjects.project_gc_untag_name, self.repo_name_untag, self.tag, self.tag, **ADMIN_CLIENT)

        #5. Tigger garbage collection operation;
        gc_id = self.system.gc_now(**ADMIN_CLIENT)

        #6. Check garbage collection job was finished;
        self.system.validate_gc_job_status(gc_id, "finished", **ADMIN_CLIENT)

        #7. Get garbage collection log, check there is a number of files was deleted;
        self.system.validate_deletion_success(gc_id, **ADMIN_CLIENT)

        artifacts = self.artifact.list_artifacts(TestProjects.project_gc_untag_name, self.repo_name_untag, **TestProjects.USER_GC_CLIENT)
        _assert_status_code(len(artifacts), 1)

        time.sleep(5)

        #9. Tigger garbage collection operation;
        gc_id = self.system.gc_now(is_delete_untagged=True, **ADMIN_CLIENT)

        #10. Check garbage collection job was finished;
        self.system.validate_gc_job_status(gc_id, "finished", **ADMIN_CLIENT)

        #7. Get garbage collection log, check there is a number of files was deleted;
        self.system.validate_deletion_success(gc_id, **ADMIN_CLIENT)

        #11. Repository with untag image should be still there;
        repo_data_untag = self.repo.list_repositories(TestProjects.project_gc_untag_name, **TestProjects.USER_GC_CLIENT)
        _assert_status_code(len(repo_data_untag), 1)
        self.assertEqual(TestProjects.project_gc_untag_name + "/" + self.repo_name_untag , repo_data_untag[0].name)

        #12. But no any artifact in repository anymore.
        artifacts = self.artifact.list_artifacts(TestProjects.project_gc_untag_name, self.repo_name_untag, **TestProjects.USER_GC_CLIENT)
        self.assertEqual(artifacts,[])
Beispiel #6
0
class TestProjects(unittest.TestCase):
    """
    Test case:
        Tag Retention
    Setup:
        Create Project test-retention
        Push image test1:1.0, test1:2.0, test1:3.0,latest, test2:1.0, test2:latest, test3:1.0, test4:1.0
    Test Steps:
        1. Create Retention Policy
        2. Add rule "For the repositories matching **, retain always with tags matching latest*"
        3. Add rule "For the repositories matching test3*, retain always with tags matching **"
        4. Dry run, check execution and tasks
        5. Real run, check images retained
    Tear Down:
        1. Delete project test-retention
    """
    @classmethod
    def setUpClass(self):
        self.user = User()
        self.system = System()
        self.repo = Repository()
        self.project = Project()
        self.retention = Retention()
        self.artifact = Artifact()
        self.repo_name_1 = "test1"

    def testTagRetention(self):
        user_ra_password = "******"
        user_ra_id, user_ra_name = self.user.create_user(
            user_password=user_ra_password, **ADMIN_CLIENT)
        print("Created user: %s, id: %s" % (user_ra_name, user_ra_id))
        TestProjects.USER_RA_CLIENT = dict(endpoint=ADMIN_CLIENT["endpoint"],
                                           username=user_ra_name,
                                           password=user_ra_password)
        TestProjects.user_ra_id = int(user_ra_id)

        TestProjects.project_src_repo_id, TestProjects.project_src_repo_name = self.project.create_project(
            metadata={"public": "false"}, **TestProjects.USER_RA_CLIENT)

        # Push image test1:1.0, test1:2.0, test1:3.0,latest, test2:1.0, test2:latest, test3:1.0
        push_special_image_to_project(TestProjects.project_src_repo_name,
                                      harbor_server, user_ra_name,
                                      user_ra_password, self.repo_name_1,
                                      ['1.0'])
        push_special_image_to_project(TestProjects.project_src_repo_name,
                                      harbor_server, user_ra_name,
                                      user_ra_password, self.repo_name_1,
                                      ['2.0'])
        push_special_image_to_project(TestProjects.project_src_repo_name,
                                      harbor_server, user_ra_name,
                                      user_ra_password, self.repo_name_1,
                                      ['3.0', 'latest'])
        push_special_image_to_project(TestProjects.project_src_repo_name,
                                      harbor_server, user_ra_name,
                                      user_ra_password, "test2", ['1.0'])
        push_special_image_to_project(TestProjects.project_src_repo_name,
                                      harbor_server, user_ra_name,
                                      user_ra_password, "test2", ['latest'])
        push_special_image_to_project(TestProjects.project_src_repo_name,
                                      harbor_server, user_ra_name,
                                      user_ra_password, "test3", ['1.0'])
        push_special_image_to_project(TestProjects.project_src_repo_name,
                                      harbor_server, user_ra_name,
                                      user_ra_password, "test4", ['1.0'])

        tags = list_image_tags(
            harbor_server,
            TestProjects.project_src_repo_name + "/" + self.repo_name_1,
            user_ra_name, user_ra_password)
        #Delete all tags of "artifact3" in repostory "image1";
        self.artifact.delete_tag(TestProjects.project_src_repo_name,
                                 self.repo_name_1, "3.0", "latest",
                                 **TestProjects.USER_RA_CLIENT)
        self.artifact.delete_tag(TestProjects.project_src_repo_name,
                                 self.repo_name_1, "3.0", "3.0",
                                 **TestProjects.USER_RA_CLIENT)
        tags = list_image_tags(
            harbor_server,
            TestProjects.project_src_repo_name + "/" + self.repo_name_1,
            user_ra_name, user_ra_password)

        resp = self.repo.list_repositories(TestProjects.project_src_repo_name,
                                           **TestProjects.USER_RA_CLIENT)
        self.assertEqual(len(resp), 4)

        # Create Retention Policy
        retention_id = self.retention.create_retention_policy(
            TestProjects.project_src_repo_id,
            selector_repository="**",
            selector_tag="latest*",
            expect_status_code=201,
            **TestProjects.USER_RA_CLIENT)

        # Add rule
        self.retention.update_retention_add_rule(retention_id,
                                                 selector_repository="test3*",
                                                 selector_tag="**",
                                                 expect_status_code=200,
                                                 **TestProjects.USER_RA_CLIENT)

        # Dry run
        self.retention.trigger_retention_policy(retention_id,
                                                dry_run=True,
                                                **TestProjects.USER_RA_CLIENT)
        time.sleep(10)
        resp = self.retention.get_retention_executions(
            retention_id, **TestProjects.USER_RA_CLIENT)
        self.assertTrue(len(resp) > 0)
        execution = resp[0]
        resp = self.retention.get_retention_exec_tasks(
            retention_id, execution.id, **TestProjects.USER_RA_CLIENT)
        self.assertEqual(len(resp), 4)
        resp = self.retention.get_retention_exec_task_log(
            retention_id, execution.id, resp[0].id,
            **TestProjects.USER_RA_CLIENT)
        #For Debug:
        print("Task 0 log begin:-----------------------------")
        i = 0
        for line in resp.split("\n"):
            print("Line" + str(i) + ": " + line)
            i = i + 1
        print("Task 0 log end:-----------------------------")

        # Real run
        self.retention.trigger_retention_policy(retention_id,
                                                dry_run=False,
                                                **TestProjects.USER_RA_CLIENT)
        time.sleep(10)
        resp = self.retention.get_retention_executions(
            retention_id, **TestProjects.USER_RA_CLIENT)
        self.assertTrue(len(resp) > 1)
        execution = resp[0]
        resp = self.retention.get_retention_exec_tasks(
            retention_id, execution.id, **TestProjects.USER_RA_CLIENT)
        self.assertEqual(len(resp), 4)
        resp = self.retention.get_retention_exec_task_log(
            retention_id, execution.id, resp[0].id,
            **TestProjects.USER_RA_CLIENT)
        print(resp)
        # TODO As the repository isn't deleted when no tags left anymore
        # TODO we should check the artifact/tag count here
        # resp=self.repo.list_repositories(TestProjects.project_src_repo_id, **TestProjects.USER_RA_CLIENT)
        # self.assertEqual(len(resp), 3)

        #List artifacts successfully;
        artifacts = self.artifact.list_artifacts(
            TestProjects.project_src_repo_name, self.repo_name_1,
            **TestProjects.USER_RA_CLIENT)
        print artifacts
        # 'test1' has 3 artifacts, artifact1 with tag '1.0' and artifact2 with tag '2.0' should be deleted because they doesn't match 'latest'
        # artifact3 should be retained because it has no tag, so count of artifacts should be 1.
        # TODO: This verfication should be enhanced by verify sha256 at the same time;
        self.assertTrue(len(artifacts) == 1)

    @classmethod
    def tearDownClass(self):
        print "Case completed"