Upgrade python and robot framework to 2.0.0

Signed-off-by: danfengliu <danfengl@vmware.com>
This commit is contained in:
danfengliu 2020-08-25 06:44:22 +00:00
parent 598e911f61
commit b5cf753b3a
77 changed files with 1083 additions and 1007 deletions

View File

@ -166,6 +166,14 @@ jobs:
./mconfig && \
make -C builddir && \
sudo make -C builddir install
python -V
sudo apt-get update -y && sudo apt-get install -y zbar-tools libzbar-dev python-zbar
sudo apt-get update -y
sudo apt-get install -y python3.6
sudo rm /usr/bin/python
sudo ln -s /usr/bin/python3.6 /usr/bin/python
sudo apt-get install -y python3-pip
python -V
- name: install
run: |
cd src/github.com/goharbor/harbor
@ -228,6 +236,14 @@ jobs:
sudo cp ./tests/harbor_ca.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates
sudo service docker restart
python -V
sudo apt-get update -y && sudo apt-get install -y zbar-tools libzbar-dev python-zbar
sudo apt-get update -y
sudo apt-get install -y python3.6
sudo rm /usr/bin/python
sudo ln -s /usr/bin/python3.6 /usr/bin/python
sudo apt-get install -y python3-pip
python -V
- name: install
run: |
cd src/github.com/goharbor/harbor

View File

@ -513,14 +513,14 @@ down:
swagger_client:
@echo "Generate swagger client"
wget -q https://repo1.maven.org/maven2/io/swagger/swagger-codegen-cli/2.3.1/swagger-codegen-cli-2.3.1.jar -O swagger-codegen-cli.jar
wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/4.3.1/openapi-generator-cli-4.3.1.jar -O openapi-generator-cli.jar
rm -rf harborclient
mkdir -p harborclient/harbor_client
mkdir -p harborclient/harbor_swagger_client
mkdir -p harborclient/harbor_v2_swagger_client
java -jar swagger-codegen-cli.jar generate -i api/swagger.yaml -l python -o harborclient/harbor_client -DpackageName=client
java -jar swagger-codegen-cli.jar generate -i api/v2.0/legacy_swagger.yaml -l python -o harborclient/harbor_swagger_client -DpackageName=swagger_client
java -jar swagger-codegen-cli.jar generate -i api/v2.0/swagger.yaml -l python -o harborclient/harbor_v2_swagger_client -DpackageName=v2_swagger_client
java -jar openapi-generator-cli.jar generate -i api/swagger.yaml -g python -o harborclient/harbor_client --package-name client
java -jar openapi-generator-cli.jar generate -i api/v2.0/legacy_swagger.yaml -g python -o harborclient/harbor_swagger_client --package-name swagger_client
java -jar openapi-generator-cli.jar generate -i api/v2.0/swagger.yaml -g python -o harborclient/harbor_v2_swagger_client --package-name v2_swagger_client
cd harborclient/harbor_client; python ./setup.py install
cd harborclient/harbor_swagger_client; python ./setup.py install
cd harborclient/harbor_v2_swagger_client; python ./setup.py install

View File

@ -1,6 +1,4 @@
# -*- coding: utf-8 -*-
import site
reload(site)
import project
import label
import registry
@ -8,7 +6,5 @@ import replication
import repository
import swagger_client
class Harbor(project.Project, label.Label,
registry.Registry, replication.Replication,
repository.Repository):
class Harbor(project.Project):
pass

View File

@ -13,7 +13,7 @@ class Artifact(base.Base, object):
client = self._get_client(**kwargs)
return client.list_artifacts(project_name, repo_name)
def get_reference_info(self, project_name, repo_name, reference, **kwargs):
def get_reference_info(self, project_name, repo_name, reference, ignore_not_found = False,**kwargs):
client = self._get_client(**kwargs)
params = {}
if "with_signature" in kwargs:
@ -22,7 +22,12 @@ class Artifact(base.Base, object):
params["with_tag"] = kwargs["with_tag"]
if "with_scan_overview" in kwargs:
params["with_scan_overview"] = kwargs["with_scan_overview"]
return client.get_artifact_with_http_info(project_name, repo_name, reference, **params)
try:
return client.get_artifact_with_http_info(project_name, repo_name, reference, **params)
except ApiException as e:
if e.status == 404 and ignore_not_found == True:
return []
def delete_artifact(self, project_name, repo_name, reference, expect_status_code = 200, expect_response_body = None, **kwargs):
client = self._get_client(**kwargs)
@ -62,10 +67,14 @@ class Artifact(base.Base, object):
base._assert_status_code(201, status_code)
return data
def create_tag(self, project_name, repo_name, reference, tag_name, expect_status_code = 201, **kwargs):
def create_tag(self, project_name, repo_name, reference, tag_name, expect_status_code = 201, ignore_conflict = False, **kwargs):
client = self._get_client(**kwargs)
tag = v2_swagger_client.Tag(name = tag_name)
_, status_code, _ = client.create_tag_with_http_info(project_name, repo_name, reference, tag)
try:
_, status_code, _ = client.create_tag_with_http_info(project_name, repo_name, reference, tag)
except ApiException as e:
if e.status == 409 and ignore_conflict == True:
return
base._assert_status_code(expect_status_code, status_code)
def delete_tag(self, project_name, repo_name, reference, tag_name, expect_status_code = 200, **kwargs):
@ -82,11 +91,13 @@ class Artifact(base.Base, object):
if (timeout_count == 0):
break
artifact = self.get_reference_info(project_name, repo_name, reference, **kwargs)
print "artifact", artifact
print "artifact[0]", artifact[0]
print "artifact[0].scan_overview", artifact[0].scan_overview
print "artifact[0].scan_overview['application/vnd.scanner.adapter.vuln.report.harbor+json; version=1.0']", artifact[0].scan_overview['application/vnd.scanner.adapter.vuln.report.harbor+json; version=1.0']
scan_status = artifact[0].scan_overview['application/vnd.scanner.adapter.vuln.report.harbor+json; version=1.0']["scan_status"]
scan_status = artifact[0].scan_overview['application/vnd.scanner.adapter.vuln.report.harbor+json; version=1.0'].scan_status
if scan_status == expected_scan_status:
return
raise Exception("Scan image result is {}, not as expected {}.".format(scan_status, expected_scan_status))
def check_reference_exist(self, project_name, repo_name, reference, ignore_not_found = False, **kwargs):
artifact = self.get_reference_info( project_name, repo_name, reference, ignore_not_found=ignore_not_found, **kwargs)
return {
0: False,
}.get(len(artifact), True)

View File

@ -1,134 +1,133 @@
# -*- coding: utf-8 -*-
import os
import sys
import time
import subprocess
import client
import swagger_client
import v2_swagger_client
try:
from urllib import getproxies
except ImportError:
from urllib.request import getproxies
class Server:
def __init__(self, endpoint, verify_ssl):
self.endpoint = endpoint
self.verify_ssl = verify_ssl
class Credential:
def __init__(self, type, username, password):
self.type = type
self.username = username
self.password = password
def get_endpoint():
harbor_server = os.environ.get("HARBOR_HOST", "localhost:8080")
return os.environ.get("HARBOR_HOST_SCHEMA", "https")+ "://"+harbor_server+"/api/v2.0"
def _create_client(server, credential, debug, api_type="products"):
cfg = None
if api_type in ('projectv2', 'artifact', 'repository', 'scan'):
cfg = v2_swagger_client.Configuration()
else:
cfg = swagger_client.Configuration()
cfg.host = server.endpoint
cfg.verify_ssl = server.verify_ssl
# support basic auth only for now
cfg.username = credential.username
cfg.password = credential.password
cfg.debug = debug
proxies = getproxies()
proxy = proxies.get('http', proxies.get('all', None))
if proxy:
cfg.proxy = proxy
if cfg.username is None and cfg.password is None:
# returns {} for auth_settings for anonymous access
import types
cfg.auth_settings = types.MethodType(lambda self: {}, cfg)
return {
"chart": client.ChartRepositoryApi(client.ApiClient(cfg)),
"products": swagger_client.ProductsApi(swagger_client.ApiClient(cfg)),
"projectv2": v2_swagger_client.ProjectApi(v2_swagger_client.ApiClient(cfg)),
"artifact": v2_swagger_client.ArtifactApi(v2_swagger_client.ApiClient(cfg)),
"repository": v2_swagger_client.RepositoryApi(v2_swagger_client.ApiClient(cfg)),
"scan": v2_swagger_client.ScanApi(v2_swagger_client.ApiClient(cfg)),
"scanner": swagger_client.ScannersApi(swagger_client.ApiClient(cfg)),
}.get(api_type,'Error: Wrong API type')
def _assert_status_code(expect_code, return_code):
if str(return_code) != str(expect_code):
raise Exception(r"HTTPS status code s not as we expected. Expected {}, while actual HTTPS status code is {}.".format(expect_code, return_code))
def _assert_status_body(expect_status_body, returned_status_body):
if expect_status_body.strip() != returned_status_body.strip():
raise Exception(r"HTTPS status body s not as we expected. Expected {}, while actual HTTPS status body is {}.".format(expect_status_body, returned_status_body))
def _random_name(prefix):
return "%s-%d" % (prefix, int(round(time.time() * 1000)))
def _get_id_from_header(header):
try:
location = header["Location"]
return int(location.split("/")[-1])
except Exception:
return None
def _get_string_from_unicode(udata):
result=''
for u in udata:
tmp = u.encode('utf8')
result = result + tmp.strip('\n\r\t')
return result
def run_command(command):
print "Command: ", subprocess.list2cmdline(command)
try:
output = subprocess.check_output(command,
stderr=subprocess.STDOUT,
universal_newlines=True)
except subprocess.CalledProcessError as e:
raise Exception('Error: Exited with error code: %s. Output:%s'% (e.returncode, e.output))
return output
class Base:
def __init__(self, server=None, credential=None, debug=True, api_type="products"):
if server is None:
server = Server(endpoint=get_endpoint(), verify_ssl=False)
if not isinstance(server.verify_ssl, bool):
server.verify_ssl = server.verify_ssl == "True"
if credential is None:
credential = Credential(type="basic_auth", username="admin", password="Harbor12345") # nosec
self.server = server
self.credential = credential
self.debug = debug
self.api_type = api_type
self.client = _create_client(server, credential, debug, api_type=api_type)
def _get_client(self, **kwargs):
if len(kwargs) == 0:
return self.client
server = self.server
if "api_type" in kwargs:
server.api_type = kwargs.get("api_type")
if "endpoint" in kwargs:
server.endpoint = kwargs.get("endpoint")
if "verify_ssl" in kwargs:
if not isinstance(kwargs.get("verify_ssl"), bool):
server.verify_ssl = kwargs.get("verify_ssl") == "True"
else:
server.verify_ssl = kwargs.get("verify_ssl")
credential = Credential(
kwargs.get("type", self.credential.type),
kwargs.get("username", self.credential.username),
kwargs.get("password", self.credential.password),
)
return _create_client(server, credential, self.debug, self.api_type)
# -*- coding: utf-8 -*-
import os
import sys
import time
import subprocess
import client
import swagger_client
import v2_swagger_client
try:
from urllib import getproxies
except ImportError:
from urllib.request import getproxies
class Server:
def __init__(self, endpoint, verify_ssl):
self.endpoint = endpoint
self.verify_ssl = verify_ssl
class Credential:
def __init__(self, type, username, password):
self.type = type
self.username = username
self.password = password
def get_endpoint():
harbor_server = os.environ.get("HARBOR_HOST", "localhost:8080")
return os.environ.get("HARBOR_HOST_SCHEMA", "https")+ "://"+harbor_server+"/api/v2.0"
def _create_client(server, credential, debug, api_type="products"):
cfg = None
if api_type in ('projectv2', 'artifact', 'repository', 'scan'):
cfg = v2_swagger_client.Configuration()
else:
cfg = swagger_client.Configuration()
cfg.host = server.endpoint
cfg.verify_ssl = server.verify_ssl
# support basic auth only for now
cfg.username = credential.username
cfg.password = credential.password
cfg.debug = debug
proxies = getproxies()
proxy = proxies.get('http', proxies.get('all', None))
if proxy:
cfg.proxy = proxy
if cfg.username is None and cfg.password is None:
# returns {} for auth_settings for anonymous access
import types
cfg.auth_settings = types.MethodType(lambda self: {}, cfg)
return {
"chart": client.ChartRepositoryApi(client.ApiClient(cfg)),
"products": swagger_client.ProductsApi(swagger_client.ApiClient(cfg)),
"projectv2": v2_swagger_client.ProjectApi(v2_swagger_client.ApiClient(cfg)),
"artifact": v2_swagger_client.ArtifactApi(v2_swagger_client.ApiClient(cfg)),
"repository": v2_swagger_client.RepositoryApi(v2_swagger_client.ApiClient(cfg)),
"scan": v2_swagger_client.ScanApi(v2_swagger_client.ApiClient(cfg)),
"scanner": swagger_client.ScannersApi(swagger_client.ApiClient(cfg)),
}.get(api_type,'Error: Wrong API type')
def _assert_status_code(expect_code, return_code):
if str(return_code) != str(expect_code):
raise Exception(r"HTTPS status code s not as we expected. Expected {}, while actual HTTPS status code is {}.".format(expect_code, return_code))
def _assert_status_body(expect_status_body, returned_status_body):
if expect_status_body.strip() != returned_status_body.strip():
raise Exception(r"HTTPS status body s not as we expected. Expected {}, while actual HTTPS status body is {}.".format(expect_status_body, returned_status_body))
def _random_name(prefix):
return "%s-%d" % (prefix, int(round(time.time() * 1000)))
def _get_id_from_header(header):
try:
location = header["Location"]
return int(location.split("/")[-1])
except Exception:
return None
def _get_string_from_unicode(udata):
result=''
for u in udata:
tmp = u.encode('utf8')
result = result + tmp.strip('\n\r\t')
return result
def run_command(command):
print("Command: ", subprocess.list2cmdline(command))
try:
output = subprocess.check_output(command,
stderr=subprocess.STDOUT,
universal_newlines=True)
except subprocess.CalledProcessError as e:
raise Exception('Error: Exited with error code: %s. Output:%s'% (e.returncode, e.output))
return output
class Base(object):
def __init__(self, server=None, credential=None, debug=True, api_type="products"):
if server is None:
server = Server(endpoint=get_endpoint(), verify_ssl=False)
if not isinstance(server.verify_ssl, bool):
server.verify_ssl = server.verify_ssl == "True"
if credential is None:
credential = Credential(type="basic_auth", username="admin", password="Harbor12345")
self.server = server
self.credential = credential
self.debug = debug
self.api_type = api_type
self.client = _create_client(server, credential, debug, api_type=api_type)
def _get_client(self, **kwargs):
if len(kwargs) == 0:
return self.client
server = self.server
if "endpoint" in kwargs:
server.endpoint = kwargs.get("endpoint")
if "verify_ssl" in kwargs:
if not isinstance(kwargs.get("verify_ssl"), bool):
server.verify_ssl = kwargs.get("verify_ssl") == "True"
else:
server.verify_ssl = kwargs.get("verify_ssl")
credential = Credential(
kwargs.get("type", self.credential.type),
kwargs.get("username", self.credential.username),
kwargs.get("password", self.credential.password),
)
return _create_client(server, credential, self.debug, kwargs.get('api_type', self.api_type))

View File

@ -17,7 +17,6 @@ class Chart(base.Base, object):
def chart_should_exist(self, repository, chart_name, **kwargs):
charts_data = self.get_charts(repository, **kwargs)
print "charts_data:", charts_data
for chart in charts_data:
if chart.name == chart_name:
return True

View File

@ -9,12 +9,9 @@ def load_bundle(service_image, invocation_image):
bundle_tmpl_file = "./tests/apitests/python/bundle_data/bundle.json.tmpl"
with open(bundle_tmpl_file,'r') as load_f:
load_dict = json.load(load_f)
print "load_dict:", load_dict
print "load_dict-invocationImages:", load_dict["invocationImages"][0]["contentDigest"]
load_dict["images"]["hello"]["image"] = service_image
load_dict["invocationImages"][0]["image"] = invocation_image
bundle_str = json.dumps(load_dict)
print "bundle_str:", bundle_str
with open(bundle_file,'w') as dump_f:
dump_f.write(bundle_str)
dump_f.close()
@ -26,16 +23,16 @@ def cnab_fixup_bundle(bundle_file, target, auto_update_bundle = True):
if auto_update_bundle == True:
command.append("--auto-update-bundle")
#fixed_bundle_file = bundle_file
print "Command: ", command
print("Command: ", command)
ret = base.run_command(command)
print "Command return: ", ret
print("Command return: ", ret)
return fixed_bundle_file
def cnab_push_bundle(bundle_file, target):
command = ["cnab-to-oci", "push", bundle_file, "--target", target, "--auto-update-bundle"]
print "Command: ", command
print("Command: ", command)
ret = base.run_command(command)
print "Command return: ", ret
print("Command return: ", ret)
for line in ret.split("\n"):
line = line.replace('\"', '')
if line.find('sha256') >= 0:
@ -48,5 +45,4 @@ def push_cnab_bundle(harbor_server, user, password, service_image, invocation_im
bundle_file = load_bundle(service_image, invocation_image)
fixed_bundle_file = cnab_fixup_bundle(bundle_file, target, auto_update_bundle = auto_update_bundle)
sha256 = cnab_push_bundle(fixed_bundle_file, target)
print "sha256:", sha256
return sha256

View File

@ -11,6 +11,16 @@ def set_configurations(client, expect_status_code = 200, expect_response_body =
conf.project_creation_restriction = config.get("project_creation_restriction")
if "token_expiration" in config:
conf.token_expiration = config.get("token_expiration")
if "ldap_filter" in config:
conf.ldap_filter = config.get("ldap_filter")
if "ldap_group_attribute_name" in config:
conf.ldap_group_attribute_name = config.get("ldap_group_attribute_name")
if "ldap_group_base_dn" in config:
conf.ldap_group_base_dn = config.get("ldap_group_base_dn")
if "ldap_group_search_filter" in config:
conf.ldap_group_search_filter = config.get("ldap_group_search_filter")
if "ldap_group_search_scope" in config:
conf.ldap_group_search_scope = config.get("ldap_group_search_scope")
try:
_, status_code, _ = client.configurations_put_with_http_info(conf)
@ -56,3 +66,11 @@ class Configurations(base.Base):
config=dict(token_expiration=token_expiration)
set_configurations(client, expect_status_code = expect_status_code, **config)
def set_configurations_of_ldap(self, ldap_filter=None, ldap_group_attribute_name=None,
ldap_group_base_dn=None, ldap_group_search_filter=None, ldap_group_search_scope=None, expect_status_code = 200, **kwargs):
client = self._get_client(**kwargs)
config=dict(ldap_filter=ldap_filter, ldap_group_attribute_name=ldap_group_attribute_name,
ldap_group_base_dn=ldap_group_base_dn, ldap_group_search_filter=ldap_group_search_filter, ldap_group_search_scope=ldap_group_search_scope)
set_configurations(client, expect_status_code = expect_status_code, **config)

View File

@ -6,15 +6,15 @@ import docker_api
def ctr_images_pull(username, password, oci):
command = ["sudo", "ctr", "images", "pull", "-u", username+":"+password, oci]
print "Command: ", command
print("Command: ", command)
ret = base.run_command(command)
print "Command return: ", ret
print("Command return: ", ret)
def ctr_images_list(oci_ref = None):
command = ["sudo", "ctr", "images", "list", "--q"]
print "Command: ", command
print("Command: ", command)
ret = base.run_command(command)
print "Command return: ", ret
print("Command return: ", ret)
if oci_ref is not None and oci_ref not in ret.split("\n"):
raise Exception(r" Get OCI ref failed, expected ref is [{}], but return ref list is [{}]".format (ret))

View File

@ -13,29 +13,29 @@ except ImportError:
def docker_info_display():
command = ["docker", "info", "-f", "'{{.OSType}}/{{.Architecture}}'"]
print "Docker Info: ", command
print("Docker Info: ", command)
ret = base.run_command(command)
print "Command return: ", ret
print("Command return: ", ret)
def docker_login_cmd(harbor_host, user, password, enable_manifest = True):
command = ["sudo", "docker", "login", harbor_host, "-u", user, "-p", password]
print "Docker Login Command: ", command
print( "Docker Login Command: ", command)
base.run_command(command)
if enable_manifest == True:
try:
ret = subprocess.check_output(["./tests/apitests/python/update_docker_cfg.sh"], shell=False)
except subprocess.CalledProcessError, exc:
except subprocess.CalledProcessError as exc:
raise Exception("Failed to update docker config, error is {} {}.".format(exc.returncode, exc.output))
def docker_manifest_create(index, manifests):
command = ["sudo", "docker","manifest","create",index]
command.extend(manifests)
print "Docker Manifest Command: ", command
print( "Docker Manifest Command: ", command)
base.run_command(command)
def docker_manifest_push(index):
command = ["sudo", "docker","manifest","push",index]
print "Docker Manifest Command: ", command
print( "Docker Manifest Command: ", command)
ret = base.run_command(command)
index_sha256=""
manifest_list=[]
@ -58,7 +58,7 @@ def list_repositories(harbor_host, user, password, n = None, last = None):
command = ["curl", "-s", "-u", user+":"+password, "https://"+harbor_host+"/v2/_catalog"+"?n=%d"%n, "--insecure"]
else:
command = ["curl", "-s", "-u", user+":"+password, "https://"+harbor_host+"/v2/_catalog", "--insecure"]
print "List Repositories Command: ", command
print( "List Repositories Command: ", command)
ret = base.run_command(command)
repos = json.loads(ret).get("repositories","")
return repos
@ -70,7 +70,7 @@ def list_image_tags(harbor_host, repository, user, password, n = None, last = No
command = ["curl", "-s", "-u", user+":"+password, "https://"+harbor_host+"/v2/"+repository+"/tags/list"+"?n=%d"%n, "--insecure"]
else:
command = ["curl", "-s", "-u", user+":"+password, "https://"+harbor_host+"/v2/"+repository+"/tags/list", "--insecure"]
print "List Image Tags Command: ", command
print( "List Image Tags Command: ", command)
ret = base.run_command(command)
tags = json.loads(ret).get("tags","")
return tags
@ -85,13 +85,13 @@ class DockerAPI(object):
expected_error_message = None
try:
self.DCLIENT.login(registry = registry, username=username, password=password)
except docker.errors.APIError, err:
except docker.errors.APIError as err:
if expected_error_message is not None:
print "docker login error:", str(err)
print( "docker login error:", str(err))
if str(err).lower().find(expected_error_message.lower()) < 0:
raise Exception(r"Docker login: Return message {} is not as expected {}".format(str(err), expected_error_message))
else:
raise Exception(r" Docker login failed, error is [{}]".format (err.message))
raise Exception(r" Docker login failed, error is [{}]".format (str(err)))
def docker_image_pull(self, image, tag = None, expected_error_message = None):
if tag is not None:
@ -103,16 +103,16 @@ class DockerAPI(object):
caught_err = False
ret = ""
try:
ret = base._get_string_from_unicode(self.DCLIENT.pull(r'{}:{}'.format(image, _tag)))
self.DCLIENT.pull(r'{}:{}'.format(image, _tag))
return ret
except Exception, err:
except Exception as err:
caught_err = True
if expected_error_message is not None:
print "docker image pull error:", str(err)
print( "docker image pull error:", str(err))
if str(err).lower().find(expected_error_message.lower()) < 0:
raise Exception(r"Pull image: Return message {} is not as expected {}".format(str(err), expected_error_message))
else:
raise Exception(r" Docker pull image {} failed, error is [{}]".format (image, err.message))
raise Exception(r" Docker pull image {} failed, error is [{}]".format (image, message))
if caught_err == False:
if expected_error_message is not None:
if str(ret).lower().find(expected_error_message.lower()) < 0:
@ -128,8 +128,8 @@ class DockerAPI(object):
try:
self.DCLIENT.tag(image, harbor_registry, _tag, force=True)
return harbor_registry, _tag
except docker.errors.APIError, e:
raise Exception(r" Docker tag image {} failed, error is [{}]".format (image, e.message))
except docker.errors.APIError as err:
raise Exception(r" Docker tag image {} failed, error is [{}]".format (image, str(err)))
def docker_image_push(self, harbor_registry, tag, expected_error_message = None):
caught_err = False
@ -137,16 +137,16 @@ class DockerAPI(object):
if expected_error_message is "":
expected_error_message = None
try:
ret = base._get_string_from_unicode(self.DCLIENT.push(harbor_registry, tag, stream=True))
self.DCLIENT.push(harbor_registry, tag)
return ret
except Exception, err:
except Exception as err:
caught_err = True
if expected_error_message is not None:
print "docker image push error:", str(err)
print( "docker image push error:", str(err))
if str(err).lower().find(expected_error_message.lower()) < 0:
raise Exception(r"Push image: Return message {} is not as expected {}".format(str(err), expected_error_message))
else:
raise Exception(r" Docker push image {} failed, error is [{}]".format (harbor_registry, err.message))
raise Exception(r" Docker push image {} failed, error is [{}]".format (harbor_registry, message))
if caught_err == False:
if expected_error_message is not None:
if str(ret).lower().find(expected_error_message.lower()) < 0:
@ -184,14 +184,14 @@ class DockerAPI(object):
self.DCLIENT.pull(repo)
image = self.DCLIENT2.images.get(repo)
return repo, image.id
except Exception, err:
except Exception as err:
caught_err = True
if expected_error_message is not None:
print "docker image build error:", str(err)
print( "docker image build error:", str(err))
if str(err).lower().find(expected_error_message.lower()) < 0:
raise Exception(r"Push image: Return message {} is not as expected {}".format(str(err), expected_error_message))
else:
raise Exception(r" Docker build image {} failed, error is [{}]".format (harbor_registry, err.message))
raise Exception(r" Docker build image {} failed, error is [{}]".format (harbor_registry, str(err)))
if caught_err == False:
if expected_error_message is not None:
if str(ret).lower().find(expected_error_message.lower()) < 0:

View File

@ -6,26 +6,26 @@ import base
def get_chart_file(file_name):
command = ["wget", file_name]
ret = base.run_command(command)
print "Command Return: ", ret
print("Command return: ", ret)
command = ["tar", "xvf", file_name.split('/')[-1]]
ret = base.run_command(command)
print "Command Return: ", ret
print("Command return: ", ret)
def helm_login(harbor_server, user, password):
os.putenv("HELM_EXPERIMENTAL_OCI", "1")
command = ["helm3", "registry", "login", harbor_server, "-u", user, "-p", password]
print "Command: ", command
print("Command: ", command)
ret = base.run_command(command)
print "Command return: ", ret
print("Command return: ", ret)
def helm_save(chart_archive, harbor_server, project, repo_name):
command = ["helm3", "chart","save", chart_archive, harbor_server+"/"+project+"/"+repo_name]
print "Command: ", command
print("Command: ", command)
base.run_command(command)
def helm_push(harbor_server, project, repo_name, version):
command = ["helm3", "chart","push", harbor_server+"/"+project+"/"+repo_name+":"+version]
print "Command: ", command
print("Command: ", command)
ret = base.run_command(command)
return ret
@ -37,11 +37,11 @@ def helm_chart_push_to_harbor(chart_file, archive, harbor_server, project, repo_
def helm2_add_repo(helm_repo_name, harbor_url, project, username, password):
command = ["helm2", "repo", "add", "--username=" + username, "--password=" + password, helm_repo_name, harbor_url + "/chartrepo/" + project]
print "Command: ", command
print("Command: ", command)
base.run_command(command)
def helm2_push(helm_repo_name, chart_file, project, username, password):
get_chart_file(chart_file)
command = ["helm2", "push", "--username=" + username, "--password=" + password, chart_file.split('/')[-1], helm_repo_name]
print "Command: ", command
print("Command: ", command)
base.run_command(command)

View File

@ -39,7 +39,6 @@ def oras_pull(harbor_server, user, password, project, repo, tag):
os.rmdir(cwd)
os.makedirs(cwd)
os.chdir(cwd)
print "Tmp dir:", cwd
except Exception as e:
raise Exception('Error: Exited with error {}',format(e))
ret = base.run_command([oras_cmd, "pull", harbor_server + "/" + project + "/" + repo+":"+ tag, "-a"])

View File

@ -47,6 +47,14 @@ class Project(base.Base):
base._assert_status_code(200, status_code)
return data
def get_project_id(self, project_name, **kwargs):
project_data = self.get_projects(dict(), **kwargs)
actual_count = len(project_data)
if actual_count == 1 and str(project_data[0].project_name) != str(project_name):
return project_data[0].project_id
else:
return None
def projects_should_exist(self, params, expected_count = None, expected_project_id = None, **kwargs):
project_data = self.get_projects(params, **kwargs)
actual_count = len(project_data)
@ -162,11 +170,16 @@ class Project(base.Base):
base._assert_status_code(expect_status_code, status_code)
base._assert_status_code(200, status_code)
def add_project_members(self, project_id, user_id, member_role_id = None, expect_status_code = 201, **kwargs):
def add_project_members(self, project_id, user_id = None, member_role_id = None, _ldap_group_dn=None,expect_status_code = 201, **kwargs):
projectMember = swagger_client.ProjectMember()
if user_id is not None:
projectMember.member_user = {"user_id": int(user_id)}
if member_role_id is None:
member_role_id = 1
_member_user = {"user_id": int(user_id)}
projectMember = swagger_client.ProjectMember(member_role_id, member_user = _member_user)
projectMember.role_id = 1
else:
projectMember.role_id = member_role_id
if _ldap_group_dn is not None:
projectMember.member_group = swagger_client.UserGroup(ldap_group_dn=_ldap_group_dn)
client = self._get_client(**kwargs)
data = []
data, status_code, header = client.projects_project_id_members_post_with_http_info(project_id, project_member = projectMember)

View File

@ -4,6 +4,7 @@ import time
import base
import v2_swagger_client
from v2_swagger_client.rest import ApiException
from library.base import _assert_status_code
class ProjectV2(base.Base, object):
def __init__(self):
@ -26,3 +27,14 @@ class ProjectV2(base.Base, object):
count = count + 1
return count
def query_user_logs(self, project_name, status_code=200, **kwargs):
try:
logs = self.get_project_log(project_name, expect_status_code=status_code, **kwargs)
count = 0
for log in list(logs):
count = count + 1
return count
except ApiException as e:
_assert_status_code(status_code, e.status)
return 0

View File

@ -38,7 +38,7 @@ class Replication(base.Base):
if str(rule_data.name) != str(expect_rule_name):
raise Exception(r"Check replication rule failed, expect <{}> actual <{}>.".format(expect_rule_name, str(rule_data.name)))
else:
print r"Check Replication rule passed, rule name <{}>.".format(str(rule_data.name))
print(r"Check Replication rule passed, rule name <{}>.".format(str(rule_data.name)))
#get_trigger = str(rule_data.trigger.kind)
#if expect_trigger is not None and get_trigger == str(expect_trigger):
# print r"Check Replication rule trigger passed, trigger name <{}>.".format(get_trigger)

View File

@ -13,9 +13,8 @@ def pull_harbor_image(registry, username, password, image, tag, expected_login_e
return
time.sleep(2)
ret = _docker_api.docker_image_pull(r'{}/{}'.format(registry, image), tag = tag, expected_error_message = expected_error_message)
print ret
def push_image_to_project(project_name, registry, username, password, image, tag, expected_login_error_message = None, expected_error_message = None, profix_for_image = None):
def push_image_to_project(project_name, registry, username, password, image, tag, expected_login_error_message = None, expected_error_message = None, profix_for_image = None, new_image=None):
_docker_api = DockerAPI()
_docker_api.docker_login(registry, username, password, expected_error_message = expected_login_error_message)
time.sleep(2)
@ -24,6 +23,8 @@ def push_image_to_project(project_name, registry, username, password, image, tag
_docker_api.docker_image_pull(image, tag = tag)
time.sleep(2)
image = new_image or image
if profix_for_image == None:
new_harbor_registry, new_tag = _docker_api.docker_image_tag(r'{}:{}'.format(image, tag), r'{}/{}/{}'.format(registry, project_name, image))
else:
@ -40,14 +41,8 @@ def push_special_image_to_project(project_name, registry, username, password, im
time.sleep(2)
if expected_login_error_message != None:
return
return _docker_api.docker_image_build(r'{}/{}/{}'.format(registry, project_name, image), tags = tags, size=size, expected_error_message=expected_error_message)
return _docker_api.docker_image_build(r'{}/{}/{}'.format(registry, project_name, image), tags = tags, size=int(size), expected_error_message=expected_error_message)
def is_repo_exist_in_project(repositories, repo_name):
result = False
for reop in repositories:
if reop.name == repo_name:
return True
return result
class Repository(base.Base, object):
def __init__(self):
@ -118,16 +113,22 @@ class Repository(base.Base, object):
if tag.scan_overview != None:
raise Exception("Image should be <Not Scanned> state!")
def repository_should_exist(self, project_id, repo_name, **kwargs):
repositories = self.list_repositories(project_id, **kwargs)
if is_repo_exist_in_project(repositories, repo_name) == False:
def repository_should_exist(self, project_Name, repo_name, **kwargs):
repositories = self.list_repositories(project_Name, **kwargs)
if repo_name not in repositories:
raise Exception("Repository {} is not exist.".format(repo_name))
def check_repository_exist(self, project_Name, repo_name, **kwargs):
repositories = self.list_repositories(project_Name, **kwargs)
for repo in repositories:
if repo.name == project_Name+"/"+repo_name:
return True
return False
def signature_should_exist(self, repo_name, tag, **kwargs):
signatures = self.get_repo_signatures(repo_name, **kwargs)
for each_sign in signatures:
if each_sign.tag == tag and len(each_sign.hashes["sha256"]) == 44:
print "sha256:", len(each_sign.hashes["sha256"])
return
raise Exception(r"Signature of {}:{} is not exist!".format(repo_name, tag))

View File

@ -5,7 +5,7 @@ from testutils import notary_url
def sign_image(registry_ip, project_name, image, tag):
try:
ret = subprocess.check_output(["./tests/apitests/python/sign_image.sh", registry_ip, project_name, image, tag, notary_url], shell=False)
print "sign_image return: ", ret
except subprocess.CalledProcessError, exc:
print("sign_image return: ", ret)
except subprocess.CalledProcessError as exc:
raise Exception("Failed to sign image error is {} {}.".format(exc.returncode, exc.output))

View File

@ -90,10 +90,10 @@ class System(base.Base):
base._assert_status_code(expect_status_code, status_code)
return data
def create_gc_schedule(self, schedule_type, cron = None, expect_status_code = 201, expect_response_body = None, **kwargs):
def create_gc_schedule(self, schedule_type, is_delete_untagged, cron = None, expect_status_code = 201, expect_response_body = None, **kwargs):
client = self._get_client(**kwargs)
gc_parameters = {'delete_untagged':True}
gc_parameters = {'delete_untagged':is_delete_untagged}
gc_schedule = swagger_client.AdminJobScheduleObj()
gc_schedule.type = schedule_type
@ -142,8 +142,8 @@ class System(base.Base):
scan_all_id = self.create_scan_all_schedule('Manual', **kwargs)
return scan_all_id
def gc_now(self, **kwargs):
gc_id = self.create_gc_schedule('Manual', **kwargs)
def gc_now(self, is_delete_untagged=False, **kwargs):
gc_id = self.create_gc_schedule('Manual', is_delete_untagged, **kwargs)
return gc_id
def validate_gc_job_status(self, gc_id, expected_gc_status, **kwargs):
@ -177,13 +177,13 @@ class System(base.Base):
def set_cve_whitelist(self, expires_at=None, expected_status_code=200, *cve_ids, **kwargs):
client = self._get_client(**kwargs)
cve_list = [swagger_client.CVEWhitelistItem(cve_id=c) for c in cve_ids]
whitelist = swagger_client.CVEWhitelist(expires_at=expires_at, items=cve_list)
whitelist = swagger_client.CVEWhitelist(expires_at=expires_at, items=cve_list)
try:
r = client.system_cve_whitelist_put_with_http_info(whitelist=whitelist, _preload_content=False)
except Exception as e:
base._assert_status_code(expected_status_code, e.status)
else:
base._assert_status_code(expected_status_code, r[1])
base._assert_status_code(expected_status_code, r.status)
def get_cve_whitelist(self, **kwargs):
client = self._get_client(**kwargs)

View File

@ -26,11 +26,11 @@ class User(base.Base):
return base._get_id_from_header(header), name
def get_users(self, username=None, email=None, page=None, page_size=None, **kwargs):
def get_users(self, user_name=None, email=None, page=None, page_size=None, **kwargs):
client = self._get_client(**kwargs)
params={}
if username is not None:
params["username"] = username
if user_name is not None:
params["username"] = user_name
if email is not None:
params["email"] = email
if page is not None:
@ -41,13 +41,19 @@ class User(base.Base):
base._assert_status_code(200, status_code)
return data
def get_user(self, user_id, **kwargs):
def get_user_by_id(self, user_id, **kwargs):
client = self._get_client(**kwargs)
data, status_code, _ = client.users_user_id_get_with_http_info(user_id)
base._assert_status_code(200, status_code)
print "data in lib:", data
return data
def get_user_by_name(self, name, **kwargs):
users = self.get_users(user_name=name, **kwargs)
for user in users:
if user.username == name:
return user
return None
def get_user_current(self, **kwargs):
client = self._get_client(**kwargs)
@ -80,7 +86,6 @@ class User(base.Base):
def update_user_role_as_sysadmin(self, user_id, IsAdmin, **kwargs):
client = self._get_client(**kwargs)
sysadmin_flag = swagger_client.SysAdminFlag(IsAdmin)
print "sysadmin_flag:", sysadmin_flag
_, status_code, _ = client.users_user_id_sysadmin_put_with_http_info(user_id, sysadmin_flag)
base._assert_status_code(200, status_code)
return user_id

View File

@ -47,7 +47,7 @@ class TestProjects(unittest.TestCase):
self.assertEqual(project_001_data, None, msg="user-001 should has no any private project, but we got {}".format(project_001_data))
#4. Add user-001 as a member of project-001
result = self.project.add_project_members(project_001_id, user_001_id, **ADMIN_CLIENT)
result = self.project.add_project_members(project_001_id, user_id=user_001_id, **ADMIN_CLIENT)
self.assertNotEqual(result, False, msg="Failed to add member user_001 to project_001, result is {}".format(result))

View File

@ -20,7 +20,7 @@ class TestProjects(unittest.TestCase):
@classmethod
def tearDown(self):
print "Case completed"
print("Case completed")
@unittest.skipIf(TEARDOWN == False, "Test data won't be erased.")
def test_ClearData(self):
@ -69,7 +69,6 @@ class TestProjects(unittest.TestCase):
#3. Create a new registry
TestProjects.registry_id, _ = self.registry.create_registry("https://" + harbor_server,**ADMIN_CLIENT)
print "TestProjects.registry_id:", TestProjects.registry_id
#4. Create a new rule for this registry;
TestProjects.rule_id, rule_name = self.replication.create_replication_policy(dest_registry=swagger_client.Registry(id=int(TestProjects.registry_id)), **ADMIN_CLIENT)

View File

@ -23,7 +23,7 @@ class TestProjects(unittest.TestCase):
@classmethod
def tearDown(self):
print "Case completed"
print("Case completed")
@unittest.skipIf(TEARDOWN == False, "Test data won't be erased.")
def test_ClearData(self):
@ -69,7 +69,7 @@ class TestProjects(unittest.TestCase):
TestProjects.project_add_g_lbl_id, TestProjects.project_add_g_lbl_name = self.project.create_project(metadata = {"public": "false"}, **ADMIN_CLIENT)
#3. Add user-001 as a member of project-001 with project-admin role
self.project.add_project_members(TestProjects.project_add_g_lbl_id, TestProjects.user_add_g_lbl_id, **ADMIN_CLIENT)
self.project.add_project_members(TestProjects.project_add_g_lbl_id, user_id=TestProjects.user_add_g_lbl_id, **ADMIN_CLIENT)
#4. Get private project of user(UA), user(UA) can see only one private project which is project(PA);
self.project.projects_should_exist(dict(public=False), expected_count = 1,

View File

@ -1,180 +1,82 @@
# coding: utf-8
"""
Harbor API
These APIs provide services for manipulating Harbor project.
OpenAPI spec version: 1.4.0
Generated by: https://github.com/swagger-api/swagger-codegen.git
"""
from __future__ import absolute_import
import os
import sys
sys.path.append(os.environ["SWAGGER_CLIENT_PATH"])
import unittest
import testutils
import docker
import swagger_client
from swagger_client.models.project import Project
from swagger_client.models.project_req import ProjectReq
from swagger_client.models.project_metadata import ProjectMetadata
from swagger_client.models.project_member import ProjectMember
from swagger_client.models.user_group import UserGroup
from swagger_client.models.configurations import Configurations
from library.projectV2 import ProjectV2
from testutils import ADMIN_CLIENT
from library.base import _assert_status_code
from v2_swagger_client.rest import ApiException
from pprint import pprint
#Testcase
#3-07-LDAP usergroup manage project group members
class TestAssignRoleToLdapGroup(unittest.TestCase):
harbor_host = os.environ["HARBOR_HOST"]
"""AssignRoleToLdapGroup unit test stubs"""
product_api = testutils.GetProductApi("admin", "Harbor12345")
repository_api = testutils.GetRepositoryApi("admin", "Harbor12345")
project_id = 0
docker_client = docker.from_env()
def setUp(self):
self.projectv2= ProjectV2()
#login with admin, create a project and assign role to ldap group
result = self.product_api.configurations_put(configurations=Configurations(ldap_filter="", ldap_group_attribute_name="cn", ldap_group_base_dn="ou=groups,dc=example,dc=com", ldap_group_search_filter="objectclass=groupOfNames", ldap_group_search_scope=2))
pprint(result)
cfgs = self.product_api.configurations_get()
pprint(cfgs)
req = ProjectReq()
req.project_name = "ldap_group_test_prj"
req.metadata = ProjectMetadata(public="false")
result = self.product_api.projects_post(req)
pprint(result)
projs = self.product_api.projects_get(name="ldap_group_test_prj")
if projs.count>0 :
project = projs[0]
self.project_id = project.project_id
# asign role to project with dn
group_dn = "cn=harbor_admin,ou=groups,dc=example,dc=com"
projectmember = ProjectMember()
projectmember.role_id = 1
projectmember.member_group = UserGroup(ldap_group_dn=group_dn)
result = self.product_api.projects_project_id_members_post( project_id=self.project_id, project_member=projectmember )
pprint(result)
group_dn = "cn=harbor_dev,ou=groups,dc=example,dc=com"
projectmember = ProjectMember()
projectmember.role_id = 2
projectmember.member_group = UserGroup(ldap_group_dn=group_dn)
result = self.product_api.projects_project_id_members_post( project_id=self.project_id, project_member=projectmember )
pprint(result)
group_dn = "cn=harbor_guest,ou=groups,dc=example,dc=com"
projectmember = ProjectMember()
projectmember.role_id = 3
projectmember.member_group = UserGroup(ldap_group_dn=group_dn)
result = self.product_api.projects_project_id_members_post( project_id=self.project_id, project_member=projectmember )
pprint(result)
pass
def tearDown(self):
#delete images in project
result = self.repository_api.delete_repository("ldap_group_test_prj", "busybox")
pprint(result)
result = self.repository_api.delete_repository("ldap_group_test_prj", "busyboxdev")
pprint(result)
if self.project_id > 0 :
self.product_api.projects_project_id_delete(self.project_id)
pass
def testAssignRoleToLdapGroup(self):
"""Test AssignRoleToLdapGroup"""
admin_product_api = testutils.GetProductApi(username="admin_user", password="zhu88jie")
projects = admin_product_api.projects_get(name="ldap_group_test_prj")
self.assertTrue(projects.count > 1)
self.assertEqual(1, projects[0].current_user_role_id)
dev_product_api = testutils.GetProductApi("dev_user", "zhu88jie")
projects = dev_product_api.projects_get(name="ldap_group_test_prj")
self.assertTrue(projects.count > 1)
self.assertEqual(2, projects[0].current_user_role_id)
guest_product_api = testutils.GetProductApi("guest_user", "zhu88jie")
projects = guest_product_api.projects_get(name="ldap_group_test_prj")
self.assertTrue(projects.count > 1)
self.assertEqual(3, projects[0].current_user_role_id)
self.dockerCmdLoginAdmin(username="admin_user", password="zhu88jie")
self.dockerCmdLoginDev(username="dev_user", password="zhu88jie")
self.dockerCmdLoginGuest(username="guest_user", password="zhu88jie")
self.assertTrue(self.queryUserLogs(username="admin_user", password="zhu88jie")>0, "admin user can see logs")
self.assertTrue(self.queryUserLogs(username="dev_user", password="zhu88jie")>0, "dev user can see logs")
self.assertTrue(self.queryUserLogs(username="guest_user", password="zhu88jie")>0, "guest user can see logs")
self.assertTrue(self.queryUserLogs(username="test", password="123456", status_code=403)==0, "test user can not see any logs")
pass
# admin user can push, pull images
def dockerCmdLoginAdmin(self, username, password):
pprint(self.docker_client.info())
self.docker_client.login(username=username, password=password, registry=self.harbor_host)
self.docker_client.images.pull("busybox:latest")
image = self.docker_client.images.get("busybox:latest")
image.tag(repository=self.harbor_host+"/ldap_group_test_prj/busybox", tag="latest")
output = self.docker_client.images.push(repository=self.harbor_host+"/ldap_group_test_prj/busybox", tag="latest")
if output.find("error")>0 :
self.fail("Should not fail to push image for admin_user")
self.docker_client.images.pull(repository=self.harbor_host+"/ldap_group_test_prj/busybox", tag="latest")
pass
# dev user can push, pull images
def dockerCmdLoginDev(self, username, password, harbor_server=harbor_host):
self.docker_client.login(username=username, password=password, registry=self.harbor_host)
self.docker_client.images.pull("busybox:latest")
image = self.docker_client.images.get("busybox:latest")
image.tag(repository=self.harbor_host+"/ldap_group_test_prj/busyboxdev", tag="latest")
output = self.docker_client.images.push(repository=self.harbor_host+"/ldap_group_test_prj/busyboxdev", tag="latest")
if output.find("error") >0 :
self.fail("Should not fail to push images for dev_user")
pass
# guest user can pull images
def dockerCmdLoginGuest(self, username, password, harbor_server=harbor_host):
self.docker_client.login(username=username, password=password, registry=self.harbor_host)
self.docker_client.images.pull("busybox:latest")
image = self.docker_client.images.get("busybox:latest")
image.tag(repository=self.harbor_host+"/ldap_group_test_prj/busyboxguest", tag="latest")
output = self.docker_client.images.push(repository=self.harbor_host+"1/ldap_group_test_prj/busyboxguest", tag="latest")
if output.find("error")<0 :
self.fail("Should failed to push image for guest user")
self.docker_client.images.pull(repository=self.harbor_host+"/ldap_group_test_prj/busybox", tag="latest")
pass
# check can see his log in current project
def queryUserLogs(self, username, password, status_code=200):
client=dict(endpoint = ADMIN_CLIENT["endpoint"], username = username, password = password)
try:
logs = self.projectv2.get_project_log("ldap_group_test_prj", status_code, **client)
count = 0
for log in list(logs):
count = count + 1
return count
except ApiException as e:
_assert_status_code(status_code, e.status)
return 0
if __name__ == '__main__':
unittest.main()
from __future__ import absolute_import
import unittest
from testutils import harbor_server
from testutils import TEARDOWN
from testutils import ADMIN_CLIENT
from testutils import created_user, created_project
from library.project import Project
from library.user import User
from library.repository import Repository
from library.repository import push_image_to_project
from library.artifact import Artifact
from library.scanner import Scanner
from library.configurations import Configurations
from library.projectV2 import ProjectV2
class TestAssignRoleToLdapGroup(unittest.TestCase):
@classmethod
def setUp(self):
self.conf= Configurations()
self.project = Project()
self.projectV2 = ProjectV2()
self.artifact = Artifact()
self.repo = Repository()
@classmethod
def tearDown(self):
print("Case completed")
def testAssignRoleToLdapGroup(self):
"""
Test case:
Assign Role To Ldap Group
Test step and expected result:
1. Set LDAP Auth configurations;
2. Create a new public project(PA) by Admin;
3. Add 3 member groups to project(PA);
4. Push image by each member role;
5. Verfify that admin_user and dev_user can push image, guest_user can not push image;
6. Verfify that admin_user, dev_user and guest_user can view logs, test user can not view logs.
7. Delete repository(RA) by user(UA);
8. Delete project(PA);
"""
url = ADMIN_CLIENT["endpoint"]
USER_ADMIN=dict(endpoint = url, username = "admin_user", password = "zhu88jie", repo = "hello-world")
USER_DEV=dict(endpoint = url, username = "dev_user", password = "zhu88jie", repo = "alpine")
USER_GUEST=dict(endpoint = url, username = "guest_user", password = "zhu88jie", repo = "busybox")
USER_TEST=dict(endpoint = url, username = "test", password = "123456")
self.conf.set_configurations_of_ldap(ldap_filter="", ldap_group_attribute_name="cn", ldap_group_base_dn="ou=groups,dc=example,dc=com",
ldap_group_search_filter="objectclass=groupOfNames", ldap_group_search_scope=2, **ADMIN_CLIENT)
with created_project(metadata={"public": "false"}) as (project_id, project_name):
self.project.add_project_members(project_id, member_role_id = 1, _ldap_group_dn = "cn=harbor_admin,ou=groups,dc=example,dc=com", **ADMIN_CLIENT)
self.project.add_project_members(project_id, member_role_id = 2, _ldap_group_dn = "cn=harbor_dev,ou=groups,dc=example,dc=com", **ADMIN_CLIENT)
self.project.add_project_members(project_id, member_role_id = 3, _ldap_group_dn = "cn=harbor_guest,ou=groups,dc=example,dc=com", **ADMIN_CLIENT)
projects = self.project.get_projects(dict(name=project_name), **USER_ADMIN)
self.assertTrue(len(projects) == 1)
self.assertEqual(1, projects[0].current_user_role_id)
repo_name_admin, _ = push_image_to_project(project_name, harbor_server, USER_ADMIN["username"], USER_ADMIN["password"], USER_ADMIN["repo"], "latest")
artifacts = self.artifact.list_artifacts(project_name, USER_ADMIN["repo"], **USER_ADMIN)
self.assertTrue(len(artifacts) == 1)
repo_name_dev, _ = push_image_to_project(project_name, harbor_server, USER_DEV["username"], USER_DEV["password"], USER_DEV["repo"], "latest")
artifacts = self.artifact.list_artifacts(project_name, USER_DEV["repo"], **USER_DEV)
self.assertTrue(len(artifacts) == 1)
push_image_to_project(project_name, harbor_server, USER_GUEST["username"], USER_GUEST["password"], USER_GUEST["repo"], "latest")
artifacts = self.artifact.list_artifacts(project_name, USER_GUEST["repo"], **USER_GUEST)
self.assertTrue(len(artifacts) == 0)
self.assertTrue(self.projectV2.query_user_logs(project_name, **USER_ADMIN)>0, "admin user can see logs")
self.assertTrue(self.projectV2.query_user_logs(project_name, **USER_DEV)>0, "dev user can see logs")
self.assertTrue(self.projectV2.query_user_logs(project_name, **USER_GUEST)>0, "guest user can see logs")
self.assertTrue(self.projectV2.query_user_logs(project_name, status_code=403, **USER_TEST)==0, "test user can not see any logs")
self.repo.delete_repoitory(project_name, repo_name_admin.split('/')[1], **USER_ADMIN)
self.repo.delete_repoitory(project_name, repo_name_dev.split('/')[1], **USER_ADMIN)
if __name__ == '__main__':
unittest.main()

View File

@ -15,7 +15,7 @@ class TestProjects(unittest.TestCase):
@classmethod
def tearDown(self):
print "Case completed"
print("Case completed")
@unittest.skipIf(TEARDOWN == False, "Test data won't be erased.")
def test_ClearData(self):

View File

@ -3,11 +3,10 @@ from __future__ import absolute_import
import unittest
from library.base import _assert_status_code
from testutils import ADMIN_CLIENT
from testutils import harbor_server
from testutils import TEARDOWN
from library.base import _assert_status_code
from library.artifact import Artifact
from library.project import Project
from library.user import User
@ -25,7 +24,7 @@ class TestProjects(unittest.TestCase):
@classmethod
def tearDownClass(self):
print "Case completed"
print("Case completed")
@unittest.skipIf(TEARDOWN == False, "Test data won't be erased.")
def test_ClearData(self):

View File

@ -3,13 +3,12 @@ from __future__ import absolute_import
import unittest
from testutils import ADMIN_CLIENT
from testutils import harbor_server
from testutils import TEARDOWN
import library.repository
import library.docker_api
from library.base import _assert_status_code
from testutils import ADMIN_CLIENT
from testutils import harbor_server
from testutils import TEARDOWN
from library.project import Project
from library.user import User
from library.repository import Repository
@ -30,7 +29,7 @@ class TestProjects(unittest.TestCase):
@classmethod
def tearDownClass(self):
print "Case completed"
print("Case completed")
@unittest.skipIf(TEARDOWN == False, "Test data won't be erased.")
def test_ClearData(self):

View File

@ -3,11 +3,10 @@ from __future__ import absolute_import
import unittest
from library.base import _assert_status_code
from testutils import ADMIN_CLIENT
from testutils import harbor_server
from testutils import TEARDOWN
from library.base import _assert_status_code
from library.project import Project
from library.user import User
from library.repository import Repository
@ -22,7 +21,7 @@ class TestProjects(unittest.TestCase):
@classmethod
def tearDownClass(self):
print "Case completed"
print("Case completed")
@unittest.skipIf(TEARDOWN == False, "Test data won't be erased.")
def test_ClearData(self):

View File

@ -16,11 +16,10 @@ class TestProjects(unittest.TestCase):
@classmethod
def tearDown(self):
print "Case completed"
print("Case completed")
@unittest.skipIf(TEARDOWN == False, "Test data won't be erased.")
def test_ClearData(self):
print "Clear trace"
#1. Delete project(PA);
self.project.delete_project(TestProjects.project_edit_project_creation_id, **TestProjects.USER_edit_project_creation_CLIENT)

View File

@ -1,15 +1,16 @@
from __future__ import absolute_import
import unittest
import time
from testutils import ADMIN_CLIENT
from testutils import TEARDOWN
from testutils import harbor_server
from library.user import User
from library.system import System
from library.project import Project
from library.repository import Repository
from library.repository import push_image_to_project
from testutils import harbor_server
from library.base import _assert_status_code
from library.repository import push_special_image_to_project
from library.artifact import Artifact
@ -28,7 +29,7 @@ class TestProjects(unittest.TestCase):
@classmethod
def tearDown(self):
print "Case completed"
print("Case completed")
@unittest.skipIf(TEARDOWN == True, "Test data won't be erased.")
def test_ClearData(self):
@ -81,6 +82,10 @@ class TestProjects(unittest.TestCase):
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)
@ -90,19 +95,22 @@ class TestProjects(unittest.TestCase):
#7. Get garbage collection log, check there is a number of files was deleted;
self.system.validate_deletion_success(gc_id, **ADMIN_CLIENT)
#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)
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(**ADMIN_CLIENT)
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)
print "repo_data_untag:", repo_data_untag
_assert_status_code(len(repo_data_untag), 1)
self.assertEqual(TestProjects.project_gc_untag_name + "/" + self.repo_name_untag , repo_data_untag[0].name)

View File

@ -1,68 +1,49 @@
# coding: utf-8
"""
Harbor API
These APIs provide services for manipulating Harbor project.
OpenAPI spec version: 1.4.0
Generated by: https://github.com/swagger-api/swagger-codegen.git
"""
from __future__ import absolute_import
import os
import sys
sys.path.append(os.environ["SWAGGER_CLIENT_PATH"])
import unittest
import testutils
import swagger_client
from swagger_client.models.project_req import ProjectReq
from swagger_client.models.configurations import Configurations
from swagger_client.rest import ApiException
from swagger_client.models.configurations import Configurations
from pprint import pprint
from testutils import harbor_server
from testutils import TEARDOWN
from testutils import ADMIN_CLIENT
from library.user import User
from library.project import Project
from library.configurations import Configurations
#Testcase
# Define a LDAP group with harbor admin
class TestLdapAdminRole(unittest.TestCase):
"""AccessLog unit test stubs"""
product_api = testutils.GetProductApi("admin", "Harbor12345")
mike_product_api = testutils.GetProductApi("mike", "zhu88jie")
project_id = 0
@classmethod
def setUp(self):
pass
url = ADMIN_CLIENT["endpoint"]
self.conf= Configurations()
self.uesr = User()
self.project = Project()
self.USER_MIKE=dict(endpoint = url, username = "mike", password = "zhu88jie")
@classmethod
def tearDown(self):
if self.project_id > 0 :
self.mike_product_api.projects_project_id_delete(project_id=self.project_id)
pass
self.project.delete_project(TestLdapAdminRole.project_id, **self.USER_MIKE)
print("Case completed")
def testLdapAdminRole(self):
"""Test LdapAdminRole"""
result = self.product_api.configurations_put(configurations=Configurations(ldap_group_admin_dn="cn=harbor_users,ou=groups,dc=example,dc=com"))
pprint(result)
"""
Test case:
LDAP Admin Role
Test step and expected result:
1. Set LDAP Auth configurations;
2. Create a new public project(PA) by LDAP user mike;
3. Check project is created successfully;
4. Check mike is not admin;
5. Delete project(PA);
"""
# Create a private project
result = self.product_api.projects_post(project=ProjectReq(project_name="test_private"))
pprint(result)
# query project with ldap user mike
projects = self.mike_product_api.projects_get(name="test_private")
self.assertTrue(projects.count>1)
self.project_id = projects[0].project_id
self.conf.set_configurations_of_ldap(ldap_group_admin_dn="cn=harbor_users,ou=groups,dc=example,dc=com", **ADMIN_CLIENT)
# check the mike is not admin in Database
user_list = self.product_api.users_get(username="mike")
pprint(user_list[0])
self.assertFalse(user_list[0].sysadmin_flag)
TestLdapAdminRole.project_id, project_name = self.project.create_project(metadata = {"public": "false"}, **self.USER_MIKE)
self.project.check_project_name_exist(name=project_name, **self.USER_MIKE)
pass
_user = self.uesr.get_user_by_name(self.USER_MIKE["username"], **ADMIN_CLIENT)
self.assertFalse(_user.sysadmin_flag)
if __name__ == '__main__':
unittest.main()
unittest.main()

View File

@ -17,7 +17,7 @@ class TestProjects(unittest.TestCase):
@classmethod
def tearDown(self):
print "Case completed"
print("Case completed")
@unittest.skipIf(TEARDOWN == False, "Test data won't be erased.")
def test_ClearData(self):

View File

@ -19,7 +19,7 @@ class TestProjects(unittest.TestCase):
@classmethod
def tearDown(self):
print "Case completed"
print("Case completed")
@unittest.skipIf(TEARDOWN == False, "Test data won't be erased.")
def test_ClearData(self):
@ -80,7 +80,7 @@ class TestProjects(unittest.TestCase):
self.project.check_project_member_not_exist(TestProjects.project_alice_id, user_bob_name, **USER_ALICE_CLIENT)
#4.1 Alice Add Bob as a guest member of project(PA)
member_id_bob = self.project.add_project_members(TestProjects.project_alice_id, TestProjects.user_bob_id, member_role_id = 3, **USER_ALICE_CLIENT)
member_id_bob = self.project.add_project_members(TestProjects.project_alice_id, user_id=TestProjects.user_bob_id, member_role_id = 3, **USER_ALICE_CLIENT)
#4.2 Check Bob is a guest member of project(PA)
self.project.check_project_members_exist(TestProjects.project_alice_id, user_bob_name, expected_member_role_id = 3, user_name = user_bob_name, user_password = user_bob_password, **USER_ALICE_CLIENT)

View File

@ -46,7 +46,7 @@ class TestProjectCVEWhitelist(unittest.TestCase):
self.user_ra_id = int(user_ra_id)
p_id, _ = self.project.create_project(metadata = {"public": "false"}, **ADMIN_CLIENT)
self.project_pa_id = int(p_id)
m_id = self.project.add_project_members(self.project_pa_id, self.user_ra_id, member_role_id=3, **ADMIN_CLIENT)
m_id = self.project.add_project_members(self.project_pa_id, user_id=self.user_ra_id, member_role_id=3, **ADMIN_CLIENT)
self.member_id = int(m_id)
def tearDown(self):

View File

@ -4,7 +4,6 @@ import unittest
from testutils import ADMIN_CLIENT
from testutils import harbor_server
from testutils import TEARDOWN
from library.artifact import Artifact
from library.project import Project
@ -23,7 +22,7 @@ class TestProjects(unittest.TestCase):
@classmethod
def tearDown(self):
print "Case completed"
print("Case completed")
@unittest.skipIf(TEARDOWN == False, "Test data won't be erased.")
def test_ClearData(self):

View File

@ -15,7 +15,7 @@ class TestProjects(unittest.TestCase):
@classmethod
def tearDown(cls):
print "Case completed"
print("Case completed")
def testProjectQuota(self):
"""

View File

@ -3,12 +3,11 @@ from __future__ import absolute_import
import unittest
import library.repository
import library.helm
from testutils import ADMIN_CLIENT, CHART_API_CLIENT
from testutils import harbor_server
from testutils import TEARDOWN
import library.repository
import library.helm
from library.project import Project
from library.user import User
from library.chart import Chart
@ -31,7 +30,7 @@ class TestProjects(unittest.TestCase):
@classmethod
def tearDownClass(self):
print "Case completed"
print("Case completed")
@unittest.skipIf(TEARDOWN == False, "Test data won't be erased.")
def test_ClearData(self):
@ -52,30 +51,27 @@ class TestProjects(unittest.TestCase):
1. Delete user(UA).
"""
print "#1. Create user(UA);"
#1. Create user(UA);
TestProjects.user_id, user_name = self.user.create_user(user_password = self.user_push_chart_password, **ADMIN_CLIENT)
TestProjects.USER_CLIENT=dict(endpoint = self.url, username = user_name, password = self.user_push_chart_password)
TestProjects.API_CHART_CLIENT=dict(endpoint = self.chart_api_url, username = user_name, password = self.user_push_chart_password)
print "#2. Create private project(PA) with user(UA);"
#2. Create private project(PA) with user(UA);
TestProjects.project_id, TestProjects.project_name = self.project.create_project(metadata = {"public": "false"}, **TestProjects.USER_CLIENT)
print "#3. Create a new robot account(RA) with full priviliges in project(PA) with user(UA);"
#3. Create a new robot account(RA) with full priviliges in project(PA) with user(UA);
robot_id, robot_account = self.project.add_project_robot_account(TestProjects.project_id, TestProjects.project_name,
2441000531 ,**TestProjects.USER_CLIENT)
print robot_account.name
print robot_account.token
print "#4. Push chart to project(PA) by Helm2 CLI with robot account(RA);"
#4. Push chart to project(PA) by Helm2 CLI with robot account(RA);"
library.helm.helm2_add_repo(self.chart_repo_name, "https://"+harbor_server, TestProjects.project_name, robot_account.name, robot_account.token)
library.helm.helm2_push(self.chart_repo_name, self.chart_file, TestProjects.project_name, robot_account.name, robot_account.token)
print "#5. Get chart repositry from project(PA) successfully;"
#5. Get chart repositry from project(PA) successfully;
self.chart.chart_should_exist(TestProjects.project_name, self.CHART_NAME, **TestProjects.API_CHART_CLIENT)
print "#6. Push chart to project(PA) by Helm3 CLI with robot account(RA);"
#6. Push chart to project(PA) by Helm3 CLI with robot account(RA);
chart_cli_ret = library.helm.helm_chart_push_to_harbor(self.chart_file, self.archive, harbor_server, TestProjects.project_name, self.repo_name, self.verion, robot_account.name, robot_account.token)
print "chart_cli_ret:", chart_cli_ret
if __name__ == '__main__':
unittest.main()

View File

@ -3,12 +3,11 @@ from __future__ import absolute_import
import unittest
import library.repository
import library.helm
from testutils import ADMIN_CLIENT
from testutils import harbor_server
from testutils import TEARDOWN
import library.repository
import library.helm
from library.project import Project
from library.user import User
from library.repository import Repository
@ -30,7 +29,7 @@ class TestProjects(unittest.TestCase):
@classmethod
def tearDownClass(self):
print "Case completed"
print("Case completed")
@unittest.skipIf(TEARDOWN == False, "Test data won't be erased.")
def test_ClearData(self):
@ -69,7 +68,6 @@ class TestProjects(unittest.TestCase):
#3. Push an chart(CA) to Harbor by helm3 registry/chart CLI successfully;
chart_cli_ret = library.helm.helm_chart_push_to_harbor(self.chart_file, self.archive, harbor_server, TestProjects.project_push_chart_name, self.repo_name, self.verion, user_name, self.user_push_chart_password)
print "chart_cli_ret:", chart_cli_ret
#4. List artifacts successfully;
artifacts = self.artifact.list_artifacts(TestProjects.project_push_chart_name, self.repo_name, **TestProjects.USER_CLIENT)

View File

@ -3,13 +3,11 @@ from __future__ import absolute_import
import unittest
import library.repository
import library.cnab
from testutils import ADMIN_CLIENT
from testutils import harbor_server
from testutils import TEARDOWN
import library.repository
import library.cnab
from library.project import Project
from library.user import User
from library.repository import Repository
@ -30,7 +28,7 @@ class TestProjects(unittest.TestCase):
@classmethod
def tearDownClass(self):
print "Case completed"
print("Case completed")
@unittest.skipIf(TEARDOWN == False, "Test data won't be erased.")
def test_ClearData(self):
@ -80,7 +78,6 @@ class TestProjects(unittest.TestCase):
#5. Get repository from Harbor successfully;
index_data = self.repo.get_repository(TestProjects.project_push_bundle_name, self.cnab_repo_name, **TestProjects.USER_CLIENT)
print "index_data:", index_data
#5.2 Cnab bundle can be pulled by ctr successfully;
# This step might not successful since ctr does't support cnab fully, it might be uncomment sometime in future.

View File

@ -2,11 +2,11 @@ from __future__ import absolute_import
import unittest
import urllib
import library.oras
from library.sign import sign_image
from testutils import ADMIN_CLIENT
from testutils import harbor_server
from testutils import TEARDOWN
import library.oras
from library.sign import sign_image
from library.user import User
from library.project import Project
from library.repository import Repository
@ -25,7 +25,7 @@ class TestProjects(unittest.TestCase):
@classmethod
def tearDown(self):
print "Case completed"
print("Case completed")
@unittest.skipIf(TEARDOWN == False, "Test data won't be erased.")
def test_ClearData(self):
@ -60,21 +60,17 @@ class TestProjects(unittest.TestCase):
#3. ORAS CLI push artifacts;
md5_list_push = library.oras.oras_push(harbor_server, user_name, user_001_password, TestProjects.project_name, self.repo_name, self.tag)
print "md5_list_push:",md5_list_push
#4. Get repository from Harbor successfully, and verfiy repository name is repo pushed by ORAS CLI;
repo_data = self.repo.get_repository(TestProjects.project_name, self.repo_name, **TestProjects.USER_CLIENT)
print "repo_data:", repo_data
self.assertEqual(repo_data.name, TestProjects.project_name + "/" + self.repo_name)
#5. Get and verify artifacts by tag;
artifact = self.artifact.get_reference_info(TestProjects.project_name, self.repo_name, self.tag, **TestProjects.USER_CLIENT)
print "artifact:", artifact
self.assertEqual(artifact[0].tags[0].name, self.tag)
#6. ORAS CLI pull artifacts index by tag;
md5_list_pull = library.oras.oras_pull(harbor_server, user_name, user_001_password, TestProjects.project_name, self.repo_name, self.tag)
print "md5_list_pull:",md5_list_pull
#7. Verfiy MD5 between artifacts pushed by ORAS and artifacts pulled by ORAS;
if set(md5_list_push) != set(md5_list_pull):

View File

@ -2,10 +2,10 @@ from __future__ import absolute_import
import unittest
import urllib
from library.sign import sign_image
from testutils import ADMIN_CLIENT
from testutils import harbor_server
from testutils import TEARDOWN
from library.sign import sign_image
from library.artifact import Artifact
from library.project import Project
from library.user import User
@ -22,7 +22,7 @@ class TestProjects(unittest.TestCase):
@classmethod
def tearDown(self):
print "Case completed"
print("Case completed")
@unittest.skipIf(TEARDOWN == False, "Test data won't be erased.")
def test_ClearData(self):
@ -63,7 +63,7 @@ class TestProjects(unittest.TestCase):
TestProjects.project_sign_image_id, TestProjects.project_sign_image_name = self.project.create_project(metadata = {"public": "false"}, **ADMIN_CLIENT)
#3. Add user(UA) as a member of project(PA) with project-admin role;
self.project.add_project_members(TestProjects.project_sign_image_id, TestProjects.user_sign_image_id, **ADMIN_CLIENT)
self.project.add_project_members(TestProjects.project_sign_image_id, user_id=TestProjects.user_sign_image_id, **ADMIN_CLIENT)
#4. Get private project of user(UA), user(UA) can see only one private project which is project(PA);
self.project.projects_should_exist(dict(public=False), expected_count = 1,
@ -77,10 +77,9 @@ class TestProjects(unittest.TestCase):
TestProjects.repo_name, tag = push_image_to_project(TestProjects.project_sign_image_name, harbor_server, user_sign_image_name, user_001_password, image, src_tag, profix_for_image=profix)
#7. Get signature of image with tag(TA), it should be exist.
full_name = urllib.quote(profix+"/"+image,'utf-8')
artifact = self.artifact.get_reference_info(TestProjects.project_sign_image_name, (str(full_name)).encode(), tag, **TestProjects.USER_sign_image_CLIENT)
full_name = urllib.parse.quote(profix+"/"+image,'utf-8')
print artifact
artifact = self.artifact.get_reference_info(TestProjects.project_sign_image_name, full_name, tag, **TestProjects.USER_sign_image_CLIENT)
self.assertEqual(artifact[0].type, 'IMAGE')
if __name__ == '__main__':

View File

@ -3,14 +3,13 @@ from __future__ import absolute_import
import unittest
from testutils import ADMIN_CLIENT
from testutils import harbor_server
from testutils import TEARDOWN
import library.repository
import library.docker_api
import library.containerd
from library.base import _assert_status_code
from testutils import ADMIN_CLIENT
from testutils import harbor_server
from testutils import TEARDOWN
from library.project import Project
from library.user import User
from library.repository import Repository
@ -34,7 +33,7 @@ class TestProjects(unittest.TestCase):
@classmethod
def tearDownClass(self):
print "Case completed"
print("Case completed")
@unittest.skipIf(TEARDOWN == False, "Test data won't be erased.")
def test_ClearData(self):

View File

@ -2,11 +2,11 @@ from __future__ import absolute_import
import unittest
import urllib
import library.singularity
from library.sign import sign_image
from testutils import ADMIN_CLIENT
from testutils import harbor_server
from testutils import TEARDOWN
import library.singularity
from library.sign import sign_image
from library.user import User
from library.project import Project
from library.repository import Repository
@ -25,7 +25,7 @@ class TestProjects(unittest.TestCase):
@classmethod
def tearDown(self):
print "Case completed"
print("Case completed")
@unittest.skipIf(TEARDOWN == False, "Test data won't be erased.")
def test_ClearData(self):
@ -63,12 +63,10 @@ class TestProjects(unittest.TestCase):
#4. Get repository from Harbor successfully, and verfiy repository name is repo pushed by singularity CLI;
repo_data = self.repo.get_repository(TestProjects.project_name, self.repo_name, **TestProjects.USER_CLIENT)
print "repo_data:", repo_data
self.assertEqual(repo_data.name, TestProjects.project_name + "/" + self.repo_name)
#5. Get and verify artifacts by tag;
artifact = self.artifact.get_reference_info(TestProjects.project_name, self.repo_name, self.tag, **TestProjects.USER_CLIENT)
print "artifact:", artifact
self.assertEqual(artifact[0].tags[0].name, self.tag)
#6. Pull sif file from harbor by singularity;

View File

@ -13,6 +13,8 @@ from library.repository import Repository
from library.repository import push_image_to_project
from library.artifact import Artifact
from library.scanner import Scanner
from library.docker_api import list_image_tags
from library.docker_api import list_repositories
import os
import library.base
import json
@ -29,7 +31,7 @@ class TestProjects(unittest.TestCase):
@classmethod
def tearDown(self):
print "Case completed"
print("Case completed")
@unittest.skipIf(TEARDOWN == False, "Test data won't be erased.")
def test_ClearData(self):
@ -84,24 +86,24 @@ class TestProjects(unittest.TestCase):
for tag in create_tags:
self.artifact.create_tag(TestProjects.project_Alice_name, self.repo_name, tag_c, tag, **USER_ALICE_CLIENT)
#4. Call the image_list_tags API
tags = library.docker_api.list_image_tags(harbor_server,TestProjects.repo_c,user_Alice_name,user_common_password)
for tag in create_tags:
tags = list_image_tags(harbor_server,TestProjects.repo_c,user_Alice_name,user_common_password)
for tag in create_tags:
self.assertTrue(tags.count(tag)>0, "Expect tag: %s is not listed"%tag)
page_tags = library.docker_api.list_image_tags(harbor_server,TestProjects.repo_c,user_Alice_name,user_common_password,len(tags)/2+1)
page_tags += library.docker_api.list_image_tags(harbor_server,TestProjects.repo_c,user_Alice_name,user_common_password,len(tags)/2+1,tags[len(tags)/2])
for tag in create_tags:
page_tags = list_image_tags(harbor_server,TestProjects.repo_c,user_Alice_name,user_common_password,len(tags)/2+1)
page_tags += list_image_tags(harbor_server,TestProjects.repo_c,user_Alice_name,user_common_password,len(tags)/2+1,tags[int(len(tags)/2)])
for tag in create_tags:
self.assertTrue(page_tags.count(tag)>0, "Expect tag: %s is not listed by the pagination query"%tag)
#5. Call the catalog API;
repos = library.docker_api.list_repositories(harbor_server,admin_user,admin_pwd)
self.assertTrue(repos.count(TestProjects.repo_a)>0 and repos.count(TestProjects.repo_b)>0 and repos.count(TestProjects.repo_c)>0, "Expected repo not found")
repos = list_repositories(harbor_server,admin_user,admin_pwd)
self.assertTrue(repos.count(TestProjects.repo_a)>0 and repos.count(TestProjects.repo_b)>0 and repos.count(TestProjects.repo_c)>0, "Expected repo not found")
for repo in [TestProjects.repo_a,TestProjects.repo_b,TestProjects.repo_c]:
self.assertTrue(repos.count(repo)>0,"Expected repo: %s is not listed"%repo)
page_repos = library.docker_api.list_repositories(harbor_server,admin_user,admin_pwd,len(repos)/2+1)
page_repos += library.docker_api.list_repositories(harbor_server,admin_user,admin_pwd,len(repos)/2+1,repos[len(repos)/2])
page_repos = list_repositories(harbor_server,admin_user,admin_pwd,len(repos)/2+1)
page_repos += list_repositories(harbor_server,admin_user,admin_pwd,len(repos)/2+1,repos[int(len(repos)/2)])
for repo in [TestProjects.repo_a,TestProjects.repo_b,TestProjects.repo_c]:
self.assertTrue(page_repos.count(repo)>0,"Expected repo: %s is not listed by the pagination query"%repo)
null_repos = library.docker_api.list_repositories(harbor_server,user_Alice_name,user_common_password)
null_repos = list_repositories(harbor_server,user_Alice_name,user_common_password)
self.assertEqual(null_repos, "")
if __name__ == '__main__':

View File

@ -25,7 +25,7 @@ class TestProjects(unittest.TestCase):
@classmethod
def tearDown(self):
print "Case completed"
print("Case completed")
@unittest.skipIf(TEARDOWN == False, "Test data won't be erased.")
def test_ClearData(self):
@ -80,7 +80,6 @@ class TestProjects(unittest.TestCase):
#3. Create a new registry;
TestProjects.registry_id, _ = self.registry.create_registry("https://hub.docker.com", registry_type="docker-hub", access_key = "", access_secret = "", insecure=False, **ADMIN_CLIENT)
print "TestProjects.registry_id:", TestProjects.registry_id
#4. Create a pull-based rule for this registry;
TestProjects.rule_id, rule_name = self.replication.create_replication_policy(src_registry=swagger_client.Registry(id=int(TestProjects.registry_id)),
@ -99,8 +98,6 @@ class TestProjects(unittest.TestCase):
#8. Check image is replicated into target project successfully.
artifact = self.artifact.get_reference_info(TestProjects.project_name, self.image, self.tag, **ADMIN_CLIENT)
print artifact
if __name__ == '__main__':
unittest.main()

View File

@ -8,7 +8,6 @@ from testutils import TEARDOWN
from testutils import harbor_server
from library.repository import push_special_image_to_project
from library.docker_api import list_image_tags
from library.retention import Retention
from library.project import Project
from library.repository import Repository
@ -64,10 +63,8 @@ class TestProjects(unittest.TestCase):
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)
print tag_data_artifact3_image1[0].digest
tag_data_artifact2_image2 = self.artifact.get_reference_info(TestProjects.project_src_repo_name, self.repo_name_2, "latest", **TestProjects.USER_RA_CLIENT)
print tag_data_artifact2_image2[0].digest
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";
@ -114,19 +111,17 @@ class TestProjects(unittest.TestCase):
#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)
print artifacts_1[0].digest
self.assertTrue(len(artifacts_1)==1)
self.assertEqual(artifacts_1[0].digest, tag_data_artifact3_image1[0].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)
print artifacts_2[0].digest
self.assertTrue(len(artifacts_2)==1)
self.assertEqual(artifacts_2[0].digest, tag_data_artifact2_image2[0].digest)
@classmethod
def tearDownClass(self):
print "Case completed"
print("Case completed")
# TODO delete_repoitory will fail when no tags left anymore
# @unittest.skipIf(TEARDOWN == False, "Test data won't be erased.")

View File

@ -4,12 +4,12 @@ import unittest
from testutils import ADMIN_CLIENT
from testutils import TEARDOWN
from testutils import harbor_server
from library.user import User
from library.project import Project
from library.repository import Repository
from library.repository import pull_harbor_image
from library.repository import push_image_to_project
from testutils import harbor_server
from library.base import _assert_status_code
class TestProjects(unittest.TestCase):
@ -21,7 +21,7 @@ class TestProjects(unittest.TestCase):
@classmethod
def tearDown(self):
print "Case completed"
print("Case completed")
@unittest.skipIf(TEARDOWN == False, "Test data won't be erased.")
def test_ClearData(self):
@ -74,58 +74,56 @@ class TestProjects(unittest.TestCase):
image_robot_account = "alpine"
tag = "latest"
print "#1. Create user(UA);"
#1. Create user(UA);"
TestProjects.user_ra_id, user_ra_name = self.user.create_user(user_password = user_ra_password, **ADMIN_CLIENT)
TestProjects.USER_RA_CLIENT=dict(endpoint = url, username = user_ra_name, password = user_ra_password)
print "#2. Create private project(PA), private project(PB) and public project(PC) by user(UA);"
#2. Create private project(PA), private project(PB) and public project(PC) by user(UA);
TestProjects.project_ra_id_a, TestProjects.project_ra_name_a = self.project.create_project(metadata = {"public": "false"}, **TestProjects.USER_RA_CLIENT)
TestProjects.project_ra_id_b, TestProjects.project_ra_name_b = self.project.create_project(metadata = {"public": "false"}, **TestProjects.USER_RA_CLIENT)
TestProjects.project_ra_id_c, TestProjects.project_ra_name_c = self.project.create_project(metadata = {"public": "true"}, **TestProjects.USER_RA_CLIENT)
print "#3. Push image(ImagePA) to project(PA), image(ImagePB) to project(PB) and image(ImagePC) to 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);
TestProjects.repo_name_in_project_a, tag_a = push_image_to_project(TestProjects.project_ra_name_a, harbor_server, user_ra_name, user_ra_password, image_project_a, tag)
TestProjects.repo_name_in_project_b, tag_b = push_image_to_project(TestProjects.project_ra_name_b, harbor_server, user_ra_name, user_ra_password, image_project_b, tag)
TestProjects.repo_name_in_project_c, tag_c = push_image_to_project(TestProjects.project_ra_name_c, harbor_server, user_ra_name, user_ra_password, image_project_c, tag)
print "#4. Create a new robot account(RA) with pull and push privilige in project(PA) by user(UA);"
#4. Create a new robot account(RA) with pull and push privilige in project(PA) by user(UA);
robot_id, robot_account = self.project.add_project_robot_account(TestProjects.project_ra_id_a, TestProjects.project_ra_name_a,
2441000531 ,**TestProjects.USER_RA_CLIENT)
print robot_account.name
print robot_account.token
print "#5. Check robot account info, it should has both pull and push priviliges;"
#5. Check robot account info, it should has both pull and push priviliges;
data = self.project.get_project_robot_account_by_id(TestProjects.project_ra_id_a, robot_id, **TestProjects.USER_RA_CLIENT)
_assert_status_code(robot_account.name, data.name)
print "#6. Pull image(ImagePA) from project(PA) by robot account(RA), it must be successful;"
#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.token, TestProjects.repo_name_in_project_a, tag_a)
print "#7. Push image(ImageRA) to 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;
TestProjects.repo_name_pa, _ = push_image_to_project(TestProjects.project_ra_name_a, harbor_server, robot_account.name, robot_account.token, image_robot_account, tag)
print "#8. Push image(ImageRA) to project(PB) by robot account(RA), it must be not successful;"
#8. Push image(ImageRA) to project(PB) by robot account(RA), it must be not successful;
push_image_to_project(TestProjects.project_ra_name_b, harbor_server, robot_account.name, robot_account.token, image_robot_account, tag, expected_error_message = "unauthorized to access repository")
print "#9. Pull image(ImagePB) from 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;
pull_harbor_image(harbor_server, robot_account.name, robot_account.token, TestProjects.repo_name_in_project_b, tag_b, expected_error_message = "unauthorized to access repository")
print "#10. Pull image from project(PC), it must be successful;"
#10. Pull image from project(PC), it must be successful;
pull_harbor_image(harbor_server, robot_account.name, robot_account.token, TestProjects.repo_name_in_project_c, tag_c)
print "#11. Push image(ImageRA) to project(PC) by robot account(RA), it must be not successful;"
#11. Push image(ImageRA) to project(PC) by robot account(RA), it must be not successful;
push_image_to_project(TestProjects.project_ra_name_c, harbor_server, robot_account.name, robot_account.token, image_robot_account, tag, expected_error_message = "unauthorized to access repository")
print "#12. Update action property of robot account(RA);"
#12. Update action property of robot account(RA);"
self.project.disable_project_robot_account(TestProjects.project_ra_id_a, robot_id, True, **TestProjects.USER_RA_CLIENT)
print "#13. Pull image(ImagePA) from project(PA) by robot account(RA), it must be not successful;"
#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.token, TestProjects.repo_name_in_project_a, tag_a, expected_login_error_message = "unauthorized: authentication required")
print "#14. Push image(ImageRA) to 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;
push_image_to_project(TestProjects.project_ra_name_a, harbor_server, robot_account.name, robot_account.token, image_robot_account, tag, expected_login_error_message = "unauthorized: authentication required")
print "#15. Delete robot account(RA), it must be not successful."
#15. Delete robot account(RA), it must be not successful.
self.project.delete_project_robot_account(TestProjects.project_ra_id_a, robot_id, **TestProjects.USER_RA_CLIENT)
if __name__ == '__main__':

View File

@ -23,7 +23,7 @@ class TestProjects(unittest.TestCase):
@classmethod
def tearDown(self):
print "Case completed"
print("Case completed")
@unittest.skipIf(TEARDOWN == True, "Test data won't be erased.")
def test_ClearData(self):
@ -66,7 +66,7 @@ class TestProjects(unittest.TestCase):
TestProjects.project_scan_image_id, TestProjects.project_scan_image_name = self.project.create_project(metadata = {"public": "false"}, **ADMIN_CLIENT)
#3. Add user(UA) as a member of project(PA) with project-admin role;
self.project.add_project_members(TestProjects.project_scan_image_id, TestProjects.user_scan_image_id, **ADMIN_CLIENT)
self.project.add_project_members(TestProjects.project_scan_image_id, user_id=TestProjects.user_scan_image_id, **ADMIN_CLIENT)
#4. Get private project of user(UA), user(UA) can see only one private project which is project(PA);
self.project.projects_should_exist(dict(public=False), expected_count = 1,

View File

@ -1,10 +1,10 @@
from __future__ import absolute_import
import unittest
from library.sign import sign_image
from testutils import ADMIN_CLIENT
from testutils import harbor_server
from testutils import TEARDOWN
from library.sign import sign_image
from library.artifact import Artifact
from library.project import Project
from library.user import User
@ -23,7 +23,7 @@ class TestProjects(unittest.TestCase):
@classmethod
def tearDown(self):
print "Case completed"
print("Case completed")
@unittest.skipIf(TEARDOWN == False, "Test data won't be erased.")
def test_ClearData(self):
@ -64,7 +64,7 @@ class TestProjects(unittest.TestCase):
TestProjects.project_sign_image_id, TestProjects.project_sign_image_name = self.project.create_project(metadata = {"public": "false"}, **ADMIN_CLIENT)
#3. Add user(UA) as a member of project(PA) with project-admin role;
self.project.add_project_members(TestProjects.project_sign_image_id, TestProjects.user_sign_image_id, **ADMIN_CLIENT)
self.project.add_project_members(TestProjects.project_sign_image_id, user_id=TestProjects.user_sign_image_id, **ADMIN_CLIENT)
#4. Get private project of user(UA), user(UA) can see only one private project which is project(PA);
self.project.projects_should_exist(dict(public=False), expected_count = 1,

View File

@ -24,7 +24,7 @@ class TestProjects(unittest.TestCase):
@classmethod
def tearDown(self):
print "Case completed"
print("Case completed")
@unittest.skipIf(TEARDOWN == False, "Test data won't be erased.")
def test_ClearData(self):

View File

@ -3,10 +3,10 @@
"""
Harbor API
These APIs provide services for manipulating Harbor project.
These APIs provide services for manipulating Harbor project.
OpenAPI spec version: 1.4.0
Generated by: https://github.com/swagger-api/swagger-codegen.git
"""
@ -22,8 +22,8 @@ import testutils
import swagger_client
from swagger_client.rest import ApiException
from swagger_client.models.user_group import UserGroup
from swagger_client.models.configurations import Configurations
from swagger_client.models.user_group import UserGroup
from swagger_client.models.configurations import Configurations
from pprint import pprint
#Testcase
@ -37,7 +37,7 @@ class TestUserGroup(unittest.TestCase):
groupId = 0
def setUp(self):
result = self.product_api.configurations_put(configurations=Configurations(ldap_group_attribute_name="cn", ldap_group_base_dn="ou=groups,dc=example,dc=com", ldap_group_search_filter="objectclass=groupOfNames", ldap_group_search_scope=2))
pprint(result)
pprint(result)
pass
def tearDown(self):
@ -50,10 +50,10 @@ class TestUserGroup(unittest.TestCase):
user_group = UserGroup(group_name="harbor_group123", group_type=1, ldap_group_dn="cn=harbor_group,ou=groups,dc=example,dc=com")
result = self.product_api.usergroups_post(usergroup=user_group)
pprint(result)
user_groups = self.product_api.usergroups_get()
found = False
for ug in user_groups :
if ug.group_name == "harbor_group123" :
found = True

View File

@ -34,7 +34,7 @@ class TestProjects(unittest.TestCase):
@classmethod
def tearDown(self):
self.test_result.get_final_result()
print "Case completed"
print("Case completed")
@unittest.skipIf(TEARDOWN == False, "Test data won't be erased.")
def test_ClearData(self):

View File

@ -3,6 +3,13 @@ import os
import sys
sys.path.insert(0, os.environ["SWAGGER_CLIENT_PATH"])
path=os.getcwd() + "/library"
sys.path.insert(0, path)
path=os.getcwd() + "/tests/apitests/python/library"
sys.path.insert(0, path)
import v2_swagger_client
from swagger_client.rest import ApiException
import swagger_client.models
@ -53,7 +60,7 @@ class TestResult(object):
def get_final_result(self):
if self.num_errors > 0:
for each_err_msg in self.error_message:
print "Error message:", each_err_msg
print("Error message:", each_err_msg)
raise Exception(r"Test case failed with {} errors.".format(self.num_errors))
from contextlib import contextmanager
@ -79,7 +86,7 @@ def created_project(name=None, metadata=None, user_id=None, member_role_id=None)
project_id, project_name = api.create_project(name=name, metadata=metadata, **ADMIN_CLIENT)
if user_id:
api.add_project_members(project_id, user_id, member_role_id=member_role_id, **ADMIN_CLIENT)
api.add_project_members(project_id, user_id=user_id, member_role_id=member_role_id, **ADMIN_CLIENT)
try:
yield (project_id, project_name)

View File

@ -25,7 +25,7 @@ fi
sudo curl -o $DIR/../../tests/apitests/python/mariadb-4.3.1.tgz https://storage.googleapis.com/harbor-builds/bin/charts/mariadb-4.3.1.tgz
sudo apt-get update && sudo apt-get install -y --no-install-recommends python-dev openjdk-7-jdk libssl-dev && sudo apt-get autoremove -y && sudo rm -rf /var/lib/apt/lists/*
sudo wget https://bootstrap.pypa.io/get-pip.py && sudo python ./get-pip.py && sudo pip install --ignore-installed urllib3 chardet requests && sudo pip install robotframework==3.0.4 robotframework-httplibrary requests dbbot robotframework-pabot --upgrade
sudo wget https://bootstrap.pypa.io/get-pip.py && sudo python ./get-pip.py && sudo pip install --ignore-installed urllib3 chardet requests && sudo pip install robotframework==3.2.1 robotframework-httplibrary requests --upgrade
sudo make swagger_client
if [ $GITHUB_TOKEN ];
then
@ -38,4 +38,5 @@ for((i=1;i<=30;i++)); do
echo $i waiting 10 seconds...
sleep 10
curl -k -L -f 127.0.0.1/api/v2.0/systeminfo && break
done
docker ps
done

View File

@ -30,7 +30,7 @@ set +e
docker ps
# run db auth api cases
if [ "$1" = 'DB' ]; then
pybot -X -v ip:$2 -v HARBOR_PASSWORD:Harbor12345 $DIR/../../tests/robot-cases/Group0-BAT/API_DB.robot
robot -X -v ip:$2 -v HARBOR_PASSWORD:Harbor12345 $DIR/../../tests/robot-cases/Group0-BAT/API_DB.robot
elif [ "$1" = 'LDAP' ]; then
# run ldap api cases
python $DIR/../../tests/configharbor.py -H $IP -u $HARBOR_ADMIN -p $HARBOR_ADMIN_PASSWD -c auth_mode=ldap_auth \
@ -39,7 +39,7 @@ elif [ "$1" = 'LDAP' ]; then
ldap_search_password=admin \
ldap_base_dn=dc=example,dc=com \
ldap_uid=cn
pybot -X -v ip:$2 -v HARBOR_PASSWORD:Harbor12345 $DIR/../../tests/robot-cases/Group0-BAT/API_LDAP.robot
robot -X -v ip:$2 -v HARBOR_PASSWORD:Harbor12345 $DIR/../../tests/robot-cases/Group0-BAT/API_LDAP.robot
else
rc=999
fi

View File

@ -36,21 +36,25 @@ Pull image
Should Not Contain ${output} No such image:
Push image
[Arguments] ${ip} ${user} ${pwd} ${project} ${image} ${sha256}=${null} ${is_robot}=${false}
${image_with_sha256}= Set Variable If '${sha256}'=='${null}' ${image} ${image}@sha256:${sha256}
${image_with_tag}= Set Variable If '${sha256}'=='${null}' ${image} ${image}:${sha256}
# If no tag provided in $(image_with_or_without_tag}, latest will be the tag pulled from docker-hub or read from local
[Arguments] ${ip} ${user} ${pwd} ${project} ${image_with_or_without_tag} ${need_pull_first}=${true} ${sha256}=${null} ${is_robot}=${false}
${d}= Get Current Date result_format=%m%s
${image_in_use}= Set Variable If '${sha256}'=='${null}' ${image_with_or_without_tag} ${image_with_or_without_tag}@sha256:${sha256}
${image_in_use_with_tag}= Set Variable If '${sha256}'=='${null}' ${image_with_or_without_tag} ${image_with_or_without_tag}:${sha256}
Sleep 3
Log To Console \nRunning docker push ${image}...
Docker Pull ${LOCAL_REGISTRY}/${LOCAL_REGISTRY_NAMESPACE}/${image_with_sha256}
Log To Console \nRunning docker push ${image_with_or_without_tag}...
${image_in_use}= Set Variable If ${need_pull_first}==${true} ${image_in_use} ${image_with_or_without_tag}
Run Keyword If ${need_pull_first}==${true} Docker Pull ${LOCAL_REGISTRY}/${LOCAL_REGISTRY_NAMESPACE}/${image_in_use}
Run Keyword If ${is_robot}==${false} Wait Unitl Command Success docker login -u ${user} -p ${pwd} ${ip}
... ELSE Wait Unitl Command Success docker login -u robot\\\$${user} -p ${pwd} ${ip}
Wait Unitl Command Success docker tag ${LOCAL_REGISTRY}/${LOCAL_REGISTRY_NAMESPACE}/${image_with_sha256} ${ip}/${project}/${image_with_tag}
Wait Unitl Command Success docker push ${ip}/${project}/${image_with_tag}
Run Keyword If ${need_pull_first}==${true} Wait Unitl Command Success docker tag ${LOCAL_REGISTRY}/${LOCAL_REGISTRY_NAMESPACE}/${image_in_use} ${ip}/${project}/${image_in_use_with_tag}
... ELSE Wait Unitl Command Success docker tag ${image_in_use} ${ip}/${project}/${image_in_use_with_tag}
Wait Unitl Command Success docker push ${ip}/${project}/${image_in_use_with_tag}
Wait Unitl Command Success docker logout ${ip}
Sleep 1
Push Image With Tag
#tag1 is tag of image on docker hub,default latest,use a version existing if you do not want to use latest
#tag1 is tag of image on docker hub,default latest,use a existed version if you do not want to use latest
[Arguments] ${ip} ${user} ${pwd} ${project} ${image} ${tag} ${tag1}=latest
Log To Console \nRunning docker push ${image}...
Docker Pull ${LOCAL_REGISTRY}/${LOCAL_REGISTRY_NAMESPACE}/${image}:${tag1}
@ -67,10 +71,11 @@ Cannot Pull Image
[Arguments] ${ip} ${user} ${pwd} ${project} ${image} ${tag}=${null} ${err_msg}=${null}
${image_with_tag}= Set Variable If '${tag}'=='${null}' ${image} ${image}:${tag}
Wait Unitl Command Success docker login -u ${user} -p ${pwd} ${ip}
:FOR ${idx} IN RANGE 0 30
\ ${out} Run Keyword And Ignore Error Command Should be Failed docker pull ${ip}/${project}/${image_with_tag}
\ Exit For Loop If '${out[0]}'=='PASS'
\ Sleep 3
FOR ${idx} IN RANGE 0 30
${out} Run Keyword And Ignore Error Command Should be Failed docker pull ${ip}/${project}/${image_with_tag}
Exit For Loop If '${out[0]}'=='PASS'
Sleep 3
END
Log To Console Cannot Pull Image - Pull Log: ${out[1]}
Should Be Equal As Strings '${out[0]}' 'PASS'
Run Keyword If '${err_msg}' != '${null}' Should Contain ${out[1]} ${err_msg}
@ -89,17 +94,19 @@ Cannot Push image
Wait Unitl Command Success docker login -u ${user} -p ${pwd} ${ip}
Wait Unitl Command Success docker tag ${LOCAL_REGISTRY}/${LOCAL_REGISTRY_NAMESPACE}/${image} ${ip}/${project}/${image}
${output}= Command Should be Failed docker push ${ip}/${project}/${image}
Log To Console ${output}
Run Keyword If '${err_msg}' != '${null}' Should Contain ${output} ${err_msg}
Run Keyword If '${err_msg_2}' != '${null}' Should Contain ${output} ${err_msg_2}
Wait Unitl Command Success docker logout ${ip}
Wait Until Container Stops
[Arguments] ${container}
:FOR ${idx} IN RANGE 0 60
\ ${out}= Run docker %{VCH-PARAMS} inspect ${container} | grep Status
\ ${status}= Run Keyword And Return Status Should Contain ${out} exited
\ Return From Keyword If ${status}
\ Sleep 1
FOR ${idx} IN RANGE 0 60
${out}= Run docker %{VCH-PARAMS} inspect ${container} | grep Status
${status}= Run Keyword And Return Status Should Contain ${out} exited
Return From Keyword If ${status}
Sleep 1
END
Fail Container did not stop within 60 seconds
Hit Nginx Endpoint
@ -123,10 +130,11 @@ Start Docker Daemon Locally
OperatingSystem.File Should Exist /usr/local/bin/dockerd-entrypoint.sh
${handle}= Start Process /usr/local/bin/dockerd-entrypoint.sh dockerd>./daemon-local.log 2>&1 shell=True
Process Should Be Running ${handle}
:FOR ${IDX} IN RANGE 5
\ ${pid}= Run pidof dockerd
\ Exit For Loop If '${pid}' != '${EMPTY}'
\ Sleep 2s
FOR ${IDX} IN RANGE 5
${pid}= Run pidof dockerd
Exit For Loop If '${pid}' != '${EMPTY}'
Sleep 2s
END
Sleep 2s
[Return] ${handle}
@ -158,7 +166,7 @@ Docker Pull
[Arguments] ${image}
${output}= Retry Keyword N Times When Error 10 Wait Unitl Command Success docker pull ${image}
Log ${output}
Log To Console Docker Pull: \n ${output}
Log To Console Docker Pull: ${output}
[Return] ${output}
Docker Tag
@ -174,3 +182,25 @@ Docker Push Index
${rc} ${output}= Run And Return Rc And Output ./tests/robot-cases/Group0-Util/docker_push_manifest_list.sh ${ip} ${user} ${pwd} ${index} ${image1} ${image2}
Log ${output}
Should Be Equal As Integers ${rc} 0
Docker Image Can Not Be Pulled
[Arguments] ${image}
FOR ${idx} IN RANGE 0 30
${out}= Run Keyword And Ignore Error Command Should be Failed docker pull ${image}
Exit For Loop If '${out[0]}'=='PASS'
Sleep 3
END
Log To Console Cannot Pull Image From Docker - Pull Log: ${out[1]}
Should Be Equal As Strings '${out[0]}' 'PASS'
Docker Image Can Be Pulled
[Arguments] ${image} ${period}=60 ${times}=10
FOR ${n} IN RANGE 1 ${times}
Sleep ${period}
${out}= Run Keyword And Ignore Error Docker Pull ${image}
Log To Console Return value is ${out[0]}
Exit For Loop If '${out[0]}'=='PASS'
Sleep 5
END
Run Keyword If '${out[0]}'=='FAIL' Capture Page Screenshot
Should Be Equal As Strings '${out[0]}' 'PASS'

View File

@ -19,10 +19,11 @@ Documentation This resource provides keywords to interact with Github
Get State Of Github Issue
[Arguments] ${num}
[Tags] secret
:FOR ${idx} IN RANGE 0 5
\ ${status} ${result}= Run Keyword And Ignore Error Get https://api.github.com/repos/vmware/vic/issues/${num}?access_token\=%{GITHUB_AUTOMATION_API_KEY}
\ Exit For Loop If '${status}'
\ Sleep 1
FOR ${idx} IN RANGE 0 5
${status} ${result}= Run Keyword And Ignore Error Get https://api.github.com/repos/vmware/vic/issues/${num}?access_token\=%{GITHUB_AUTOMATION_API_KEY}
Exit For Loop If '${status}'
Sleep 1
END
Should Be Equal ${result.status_code} ${200}
${status}= Get From Dictionary ${result.json()} state
[Return] ${status}

View File

@ -325,8 +325,9 @@ Add Items To System CVE Whitelist
Delete Top Item In System CVE Whitelist
[Arguments] ${count}=1
:FOR ${idx} IN RANGE 1 ${count}
\ Retry Element Click ${configuration_system_wl_delete_a_cve_id_icon}
FOR ${idx} IN RANGE 1 ${count}
Retry Element Click ${configuration_system_wl_delete_a_cve_id_icon}
END
Retry Element Click ${config_system_save_button_xpath}
Get Project Count Quota Text From Project Quotas List

View File

@ -43,8 +43,9 @@ Go Into Chart Detail
Multi-delete Chart Files
[Arguments] @{obj}
Switch To Project Charts
:For ${obj} in @{obj}
\ Retry Element Click //clr-dg-row[contains(.,'${obj}')]//label
FOR ${obj} IN @{obj}
Retry Element Click //clr-dg-row[contains(.,'${obj}')]//label
END
#Retry Element Click xpath=${version_checkbox}
Capture Page Screenshot
Retry Double Keywords When Error Retry Element Click xpath=${version_delete} Retry Wait Until Page Contains Element ${version_confirm_delete}

View File

@ -21,8 +21,9 @@ View Repo Scan Details
[Arguments] @{vulnerabilities_level}
Retry Element Click xpath=${first_repo_xpath}
Capture Page Screenshot
:FOR ${item} IN @{vulnerabilities_level}
\ Retry Wait Until Page Contains Element //hbr-artifact-vulnerabilities//clr-dg-row[contains(.,'${item}')]
FOR ${item} IN @{vulnerabilities_level}
Retry Wait Until Page Contains Element //hbr-artifact-vulnerabilities//clr-dg-row[contains(.,'${item}')]
END
Retry Element Click xpath=${build_history_btn}
Retry Wait Until Page Contains Element xpath=${build_history_data}

View File

@ -81,10 +81,11 @@ Set Daily Schedule
Execute Result Should Be
[Arguments] ${result}
:FOR ${idx} IN RANGE 0 20
\ ${out} Run Keyword And Ignore Error Retry Wait Until Page Contains Element xpath=//clr-dg-cell[contains(., '${result}')]
\ Exit For Loop If '${out[0]}'=='PASS'
\ Sleep 6
FOR ${idx} IN RANGE 0 20
${out} Run Keyword And Ignore Error Retry Wait Until Page Contains Element xpath=//clr-dg-cell[contains(., '${result}')]
Exit For Loop If '${out[0]}'=='PASS'
Sleep 6
END
Should Be Equal As Strings '${out[0]}' 'PASS'
Execute Dry Run

View File

@ -198,14 +198,16 @@ Do Log Advanced Search
Retry Click Repo Name
[Arguments] ${repo_name_element}
:For ${n} IN RANGE 1 10
\ ${out} Run Keyword And Ignore Error Retry Double Keywords When Error Retry Element Click ${repo_name_element} Retry Wait Element ${tag_table_column_vulnerabilities}
\ Exit For Loop If '${out[0]}'=='PASS'
FOR ${n} IN RANGE 1 10
${out} Run Keyword And Ignore Error Retry Double Keywords When Error Retry Element Click ${repo_name_element} Retry Wait Element ${tag_table_column_vulnerabilities}
Exit For Loop If '${out[0]}'=='PASS'
END
Should Be Equal As Strings '${out[0]}' 'PASS'
:For ${n} IN RANGE 1 10
\ ${out} Run Keyword And Ignore Error Retry Wait Until Page Not Contains Element ${repo_list_spinner}
\ Exit For Loop If '${out[0]}'=='PASS'
FOR ${n} IN RANGE 1 10
${out} Run Keyword And Ignore Error Retry Wait Until Page Not Contains Element ${repo_list_spinner}
Exit For Loop If '${out[0]}'=='PASS'
END
Should Be Equal As Strings '${out[0]}' 'PASS'
Go Into Repo
@ -214,15 +216,16 @@ Go Into Repo
Retry Wait Until Page Not Contains Element ${repo_list_spinner}
${repo_name_element}= Set Variable xpath=//clr-dg-cell[contains(.,'${repoName}')]/a
Retry Element Click ${repo_search_icon}
:For ${n} IN RANGE 1 10
\ Retry Clear Element Text ${repo_search_input}
\ Retry Text Input ${repo_search_input} ${repoName}
\ ${out} Run Keyword And Ignore Error Retry Wait Until Page Contains Element ${repo_name_element}
\ Sleep 2
\ Continue For Loop If '${out[0]}'=='FAIL'
\ ${out} Retry Click Repo Name ${repo_name_element}
\ Sleep 2
\ Exit For Loop
FOR ${n} IN RANGE 1 10
Retry Clear Element Text ${repo_search_input}
Retry Text Input ${repo_search_input} ${repoName}
${out} Run Keyword And Ignore Error Retry Wait Until Page Contains Element ${repo_name_element}
Sleep 2
Continue For Loop If '${out[0]}'=='FAIL'
${out} Retry Click Repo Name ${repo_name_element}
Sleep 2
Exit For Loop
END
Click Index Achieve
@ -232,11 +235,12 @@ Click Index Achieve
Go Into Index And Contain Artifacts
[Arguments] ${tag_name} ${limit}=3
Retry Double Keywords When Error Click Index Achieve ${tag_name} Page Should Contain Element ${tag_table_column_os_arch}
:For ${n} IN RANGE 1 10
\ ${out} Run Keyword And Ignore Error Page Should Contain Element ${artifact_rows} limit=${limit}
\ Exit For Loop If '${out[0]}'=='PASS'
\ Capture Page Screenshot gointo_${tag_name}.png
\ Sleep 3
FOR ${n} IN RANGE 1 10
${out} Run Keyword And Ignore Error Page Should Contain Element ${artifact_rows} limit=${limit}
Exit For Loop If '${out[0]}'=='PASS'
Capture Page Screenshot gointo_${tag_name}.png
Sleep 3
END
Run Keyword If '${out[0]}'=='FAIL' Capture Page Screenshot
Should Be Equal As Strings '${out[0]}' 'PASS'

View File

@ -19,7 +19,7 @@ Resource ../../resources/Util.robot
*** Variables ***
*** Keywords ***
Filter Replicatin Rule
Filter Replication Rule
[Arguments] ${ruleName}
${rule_name_element}= Set Variable xpath=//clr-dg-cell[contains(.,'${ruleName}')]
Retry Element Click ${filter_rules_btn}
@ -27,6 +27,16 @@ Filter Replicatin Rule
Retry Wait Until Page Contains Element ${rule_name_element}
Capture Page Screenshot filter_replic_${ruleName}.png
Filter Registry
[Arguments] ${registry_name}
${registry_name_element}= Set Variable xpath=//clr-dg-cell[contains(.,'${registry_name}')]
Switch To Replication Manage
Switch To Registries
Retry Element Click ${filter_registry_btn}
Retry Text Input ${filter_registry_input} ${registry_name}
Retry Wait Until Page Contains Element ${registry_name_element}
Capture Page Screenshot filter_repistry_${registry_name}.png
Select Dest Registry
[Arguments] ${endpoint}
Retry Element Click ${dest_registry_dropdown_list}
@ -68,27 +78,28 @@ Create A New Endpoint
#cancel verify cert since we use a selfsigned cert
Retry Element Click ${destination_insecure_xpath}
Run Keyword If '${save}' == 'Y' Run keyword Retry Double Keywords When Error Retry Element Click ${replication_save_xpath} Retry Wait Until Page Not Contains Element ${replication_save_xpath}
Run Keyword If '${save}' == 'Y' Run keyword Retry Wait Until Page Contains ${name}
Run Keyword If '${save}' == 'Y' Run keyword Filter Registry ${name}
Run Keyword If '${save}' == 'N' No Operation
Create A Rule With Existing Endpoint
[Arguments] ${name} ${replication_mode} ${project_name} ${resource_type} ${endpoint} ${dest_namespace}
... ${mode}=Manual ${cron}="* */59 * * * *"
[Arguments] ${name} ${replication_mode} ${filter_project_name} ${resource_type} ${endpoint} ${dest_namespace}
... ${mode}=Manual ${cron}="* */59 * * * *" ${del_remote}=${false} ${filter_tag}=${false}
#click new
Retry Element Click ${new_name_xpath}
#input name
Retry Text Input ${rule_name} ${name}
Run Keyword If '${replication_mode}' == 'push' Run Keywords Retry Element Click ${replication_mode_radio_push}
... AND Select Dest Registry ${endpoint}
... ELSE Run Keywords Retry Element Click ${replication_mode_radio_pull}
... AND Select Source Registry ${endpoint}
Run Keyword If '${replication_mode}' == 'push' Run Keywords Retry Element Click ${replication_mode_radio_push} AND Select Dest Registry ${endpoint}
... ELSE Run Keywords Retry Element Click ${replication_mode_radio_pull} AND Select Source Registry ${endpoint}
#set filter
Retry Text Input ${source_project} ${project_name}
Retry Text Input ${filter_name_id} ${filter_project_name}
Run Keyword If '${filter_tag}' != '${false}' Retry Text Input ${filter_tag_id} ${filter_tag}
Run Keyword And Ignore Error Select From List By Value ${rule_resource_selector} ${resource_type}
Retry Text Input ${dest_namespace_xpath} ${dest_namespace}
#set trigger
Select Trigger ${mode}
Run Keyword If '${mode}' == 'Scheduled' Retry Text Input ${targetCron_id} ${cron}
Run Keyword If '${mode}' == 'Scheduled' Retry Text Input ${targetCron_id} ${cron}
Run Keyword If '${mode}' == 'Event Based' and '${del_remote}' == '${true}' Retry Element Click ${del_remote_checkbox}
#click save
Retry Double Keywords When Error Retry Element Click ${rule_save_button} Retry Wait Until Page Not Contains Element ${rule_save_button}
Sleep 2
@ -225,7 +236,7 @@ Delete Endpoint
Select Rule And Replicate
[Arguments] ${rule_name}
Retry Element Click //hbr-list-replication-rule//clr-dg-cell[contains(.,'${rule_name}')]
Select Rule ${rule_name}
Retry Element Click ${replication_exec_id}
Retry Double Keywords When Error Retry Element Click xpath=${dialog_replicate} Retry Wait Until Page Not Contains Element xpath=${dialog_replicate}
@ -245,15 +256,25 @@ Delete Replication Rule
Retry Element Click ${dialog_delete}
Image Should Be Replicated To Project
[Arguments] ${project} ${image} ${period}=60 ${times}=10
:For ${n} IN RANGE 1 ${times}
\ Sleep ${period}
\ Go Into Project ${project}
\ Switch To Project Repo
\ #In AWS-ECR, under repository a, there're only several images: httpd,alpine,hello-world.
\ ${out} Run Keyword And Ignore Error Retry Wait Until Page Contains ${project}/${image}
\ Log To Console Return value is ${out[0]}
\ Exit For Loop If '${out[0]}'=='PASS'
\ Sleep 5
[Arguments] ${project} ${image} ${period}=60 ${times}=3
FOR ${n} IN RANGE 0 ${times}
Sleep ${period}
Go Into Project ${project}
Switch To Project Repo
#In AWS-ECR, under repository a, there're only several images: httpd,alpine,hello-world.
${out} Run Keyword And Ignore Error Retry Wait Until Page Contains ${project}/${image}
Log To Console Return value is ${out[0]}
Exit For Loop If '${out[0]}'=='PASS'
Sleep 5
END
Run Keyword If '${out[0]}'=='FAIL' Capture Page Screenshot
Should Be Equal As Strings '${out[0]}' 'PASS'
Should Be Equal As Strings '${out[0]}' 'PASS'
Executions Result Count Should Be
[Arguments] ${expected_status} ${expected_trigger_type} ${expected_result_count}
Sleep 10
${count}= Get Element Count xpath=//clr-dg-row[contains(.,'${expected_status}') and contains(.,'${expected_trigger_type}')]
Capture Page Screenshot
Should Be Equal As Integers ${count} ${expected_result_count}
Capture Page Screenshot

View File

@ -23,7 +23,7 @@ ${policy_enable_checkbox} //input[@id='policy_enable']/../label
${policy_endpoint_checkbox} //input[@id='check_new']/../label
${destination_name_xpath} //*[@id='destination_name']
${destination_url_xpath} //*[@id='destination_url']
${destination_username_xpath} //*[@id='destination_access_key']
${destination_username_xpath} //*[@id='destination_access_key']
${destination_password_xpath} //*[@id='destination_password']
${replication_save_xpath} //button[contains(.,'OK')]
${replication_xpath} //clr-vertical-nav-group-children/a[contains(.,'Replication')]
@ -41,7 +41,7 @@ ${rule_trigger_select} //select[@id='ruleTrigger']
${schedule_type_select} //select[@name='scheduleType']
${schedule_day_select} //select[@name='scheduleDay']
${shcedule_time} //input[@type='time']
${destination_insecure_checkbox} //hbr-create-edit-endpoint/clr-modal//input[@id='destination_insecure']
${destination_insecure_checkbox} //hbr-create-edit-endpoint/clr-modal//input[@id='destination_insecure']
${ping_test_button} //button[contains(.,'Test')]
${nav_to_registries} //clr-vertical-nav//span[contains(.,'Registries')]
${nav_to_replications} //clr-vertical-nav//span[contains(.,'Replications')]
@ -59,29 +59,32 @@ ${dialog_delete} //clr-modal//button[contains(.,'DELETE')]
${dialog_replicate} //clr-modal//button[contains(.,'REPLICATE')]
${action_bar_replicate} //button[contains(.,'Replicate')]
${rule_save_button} //button[contains(.,'SAVE')]
${provider_selector} //*[@id='adapter']
${replication_mode_radio_push} //clr-main-container//hbr-create-edit-rule//label[contains(.,'Push-based')]
${replication_mode_radio_pull} //clr-main-container//hbr-create-edit-rule//label[contains(.,'Pull-based')]
${source_project} //input[@id='filter_name']
${rule_resource_selector} //*[@id='select_resource']
${trigger_mode_selector} //*[@id='ruleTrigger']
${dest_namespace_xpath} //*[@id='dest_namespace']
${new_replication_rule_id} //*[@id='new_replication_rule_id']
${edit_replication_rule_id} //*[@id='edit_replication_rule_id']
${delete_replication_rule_id} //*[@id='delete_replication_rule_id']
${replication_exec_id} //*[@id='replication_exe_id']
${replication_task_line_1} //clr-datagrid//clr-dg-row/div/div[2]//clr-checkbox-wrapper/label[1]
${filter_tag} //*[@id='filter_tag']
${is_overide_xpath} //label[contains(.,'Replace the destination resources if name exists')]
${enable_rule_xpath} //label[contains(.,'Enable rule')]
${targetCron_id} //*[@id='targetCron']
${rule_name_input} //*[@id='ruleName']
${src_registry_dropdown_list} //select[@id='src_registry_id']
${dest_registry_dropdown_list} //select[@id='dest_registry']
${rule_confirm_btn} //*[@id='ruleBtnOk']
${rule_cancel_btn} //*[@id='ruleBtnCancel']
${filter_rules_btn} //*[@id='filter-rules']
${provider_selector} //*[@id='adapter']
${replication_mode_radio_push} //clr-main-container//hbr-create-edit-rule//label[contains(.,'Push-based')]
${replication_mode_radio_pull} //clr-main-container//hbr-create-edit-rule//label[contains(.,'Pull-based')]
${filter_name_id} //input[@id='filter_name']
${filter_tag_id} //input[@id='filter_tag']
${rule_resource_selector} //*[@id='select_resource']
${trigger_mode_selector} //*[@id='ruleTrigger']
${dest_namespace_xpath} //*[@id='dest_namespace']
${new_replication_rule_id} //*[@id='new_replication_rule_id']
${edit_replication_rule_id} //*[@id='edit_replication_rule_id']
${delete_replication_rule_id} //*[@id='delete_replication_rule_id']
${replication_exec_id} //*[@id='replication_exe_id']
${replication_task_line_1} //clr-datagrid//clr-dg-row/div/div[2]//clr-checkbox-wrapper/label[1]
${is_overide_xpath} //label[contains(.,'Replace the destination resources if name exists')]
${enable_rule_xpath} //label[contains(.,'Enable rule')]
${targetCron_id} //*[@id='targetCron']
${rule_name_input} //*[@id='ruleName']
${src_registry_dropdown_list} //select[@id='src_registry_id']
${dest_registry_dropdown_list} //select[@id='dest_registry']
${rule_confirm_btn} //*[@id='ruleBtnOk']
${rule_cancel_btn} //*[@id='ruleBtnCancel']
${filter_rules_btn} //*[@id='filter-rules']
${filter_rules_input} //*[@id='filter-rules']//input
${del_remote_checkbox} //label[@for='ruleDeletion']
${filter_registry_btn} //hbr-filter
${filter_registry_input} //input[contains(@class,'filter-input')]

View File

@ -21,15 +21,17 @@ Resource ../../resources/Util.robot
*** Keywords ***
Delete Success
[Arguments] @{obj}
:For ${obj} in @{obj}
\ Retry Wait Until Page Contains Element //*[@id='contentAll']//div[contains(.,'${obj}')]/../div/clr-icon[@shape='success-standard']
FOR ${obj} IN @{obj}
Retry Wait Until Page Contains Element //*[@id='contentAll']//div[contains(.,'${obj}')]/../div/clr-icon[@shape='success-standard']
END
Sleep 1
Capture Page Screenshot
Delete Fail
[Arguments] @{obj}
:For ${obj} in @{obj}
\ Retry Wait Until Page Contains Element //*[@id='contentAll']//div[contains(.,'${obj}')]/../div/clr-icon[@shape='error-standard']
FOR ${obj} IN @{obj}
Retry Wait Until Page Contains Element //*[@id='contentAll']//div[contains(.,'${obj}')]/../div/clr-icon[@shape='error-standard']
END
Sleep 1
Capture Page Screenshot
@ -46,7 +48,7 @@ Filter Object
Filter Project
#Filter project repo user tag.
[Arguments] ${kw}
Retry Element Click ${log_xpath}
Retry Element Click ${log_xpath}
Retry Element Click ${projects_xpath}
Filter Object ${kw}
@ -57,9 +59,10 @@ Select Object
Multi-delete Object
[Arguments] ${delete_btn} @{obj}
:For ${obj} in @{obj}
\ ${element}= Set Variable xpath=//clr-dg-row[contains(.,'${obj}')]//label
\ Retry Element Click ${element}
FOR ${obj} IN @{obj}
${element}= Set Variable xpath=//clr-dg-row[contains(.,'${obj}')]//label
Retry Element Click ${element}
END
Sleep 1
Capture Page Screenshot
Retry Element Click ${delete_btn}
@ -73,9 +76,10 @@ Multi-delete Object
# This func cannot support as the delete user flow changed.
Multi-delete Artifact
[Arguments] ${delete_btn} @{obj}
:For ${obj} in @{obj}
\ ${element}= Set Variable xpath=//clr-dg-row[contains(.,'${obj}')]//label
\ Retry Element Click ${element}
FOR ${obj} IN @{obj}
${element}= Set Variable xpath=//clr-dg-row[contains(.,'${obj}')]//label
Retry Element Click ${element}
END
Sleep 1
Capture Page Screenshot
Retry Element Click ${artifact_action_xpath}
@ -90,8 +94,9 @@ Multi-delete Artifact
Multi-delete User
[Arguments] @{obj}
:For ${obj} in @{obj}
\ Retry Element Click //clr-dg-row[contains(.,'${obj}')]//label
FOR ${obj} IN @{obj}
Retry Element Click //clr-dg-row[contains(.,'${obj}')]//label
END
Retry Element Click ${member_action_xpath}
Retry Element Click //*[@id='deleteUser']
Retry Double Keywords When Error Retry Element Click ${delete_btn} Retry Wait Until Page Not Contains Element ${delete_btn}
@ -99,8 +104,9 @@ Multi-delete User
Multi-delete Member
[Arguments] @{obj}
:For ${obj} in @{obj}
\ Retry Element Click //clr-dg-row[contains(.,'${obj}')]//clr-checkbox-wrapper/label
FOR ${obj} IN @{obj}
Retry Element Click //clr-dg-row[contains(.,'${obj}')]//clr-checkbox-wrapper/label
END
Retry Double Keywords When Error Retry Element Click ${member_action_xpath} Retry Wait Until Page Contains Element ${delete_action_xpath}
Retry Double Keywords When Error Retry Element Click ${delete_action_xpath} Retry Wait Until Page Contains Element ${delete_btn}
Retry Double Keywords When Error Retry Element Click ${delete_btn} Retry Wait Until Page Not Contains Element ${delete_btn}
@ -108,8 +114,9 @@ Multi-delete Member
Multi-delete Object Without Confirmation
[Arguments] @{obj}
:For ${obj} in @{obj}
\ Retry Element Click //clr-dg-row[contains(.,'${obj}')]//label
FOR ${obj} IN @{obj}
Retry Element Click //clr-dg-row[contains(.,'${obj}')]//label
END
Retry Double Keywords When Error Retry Element Click ${delete_btn_2} Retry Wait Until Page Not Contains Element ${delete_btn_2}

View File

@ -11,14 +11,16 @@ Verify User
Sign In Harbor ${HARBOR_URL} ${HARBOR_ADMIN} ${HARBOR_PASSWORD}
Switch To User Tag
@{user}= Get Value From Json ${json} $.users..name
:FOR ${user} IN @{user}
\ Page Should Contain ${user}
FOR ${user} IN @{user}
Page Should Contain ${user}
END
Logout Harbor
#verify user can login
@{user}= Get Value From Json ${json} $.users..name
:FOR ${user} IN @{user}
\ Sign In Harbor ${HARBOR_URL} ${user} ${HARBOR_PASSWORD}
\ Logout Harbor
FOR ${user} IN @{user}
Sign In Harbor ${HARBOR_URL} ${user} ${HARBOR_PASSWORD}
Logout Harbor
END
Close Browser
Verify Project
@ -27,8 +29,9 @@ Verify Project
@{project}= Get Value From Json ${json} $.projects.[*].name
Init Chrome Driver
Sign In Harbor ${HARBOR_URL} ${HARBOR_ADMIN} ${HARBOR_PASSWORD}
:FOR ${project} IN @{project}
\ Retry Wait Until Page Contains ${project}
FOR ${project} IN @{project}
Retry Wait Until Page Contains ${project}
END
Verify Project Metadata ${json}
Close Browser
@ -38,13 +41,14 @@ Verify Image Tag
@{project}= Get Value From Json ${json} $.projects.[*].name
Init Chrome Driver
Sign In Harbor ${HARBOR_URL} ${HARBOR_ADMIN} ${HARBOR_PASSWORD}
:FOR ${project} IN @{project}
\ @{out_has_image}= Get Value From Json ${json} $.projects[?(@.name=${project})].has_image
\ ${has_image} Set Variable If @{out_has_image}[0] == ${true} ${true} ${false}
\ Go Into Project ${project} has_image=${has_image}
\ @{repo}= Get Value From Json ${json} $.projects[?(@.name=${project})]..repo..name
\ Run Keyword If ${has_image} == ${true} Loop Image Repo @{repo}
\ Navigate To Projects
FOR ${project} IN @{project}
@{out_has_image}= Get Value From Json ${json} $.projects[?(@.name=${project})].has_image
${has_image} Set Variable If @{out_has_image}[0] == ${true} ${true} ${false}
Go Into Project ${project} has_image=${has_image}
@{repo}= Get Value From Json ${json} $.projects[?(@.name=${project})]..repo..name
Run Keyword If ${has_image} == ${true} Loop Image Repo @{repo}
Navigate To Projects
END
Close Browser
Verify Project Metadata
@ -52,19 +56,20 @@ Verify Project Metadata
@{project}= Get Value From Json ${json} $.projects.[*].name
Init Chrome Driver
Sign In Harbor ${HARBOR_URL} ${HARBOR_ADMIN} ${HARBOR_PASSWORD}
:FOR ${project} IN @{project}
\ @{out_has_image}= Get Value From Json ${json} $.projects[?(@.name=${project})].has_image
\ ${has_image} Set Variable If @{out_has_image}[0] == ${true} ${true} ${false}
\ Go Into Project ${project} has_image=${has_image}
\ Switch To Project Configuration
\ Verify Checkbox ${json} $.projects[?(@.name=${project})].configuration.public ${project_config_public_checkbox}
\ Verify Checkbox ${json} $.projects[?(@.name=${project})].configuration.enable_content_trust ${project_config_content_trust_checkbox}
\ Verify Checkbox ${json} $.projects[?(@.name=${project})].configuration.auto_scan ${project_config_scan_images_on_push_checkbox}
\ Verify Checkbox ${json} $.projects[?(@.name=${project})].configuration.prevent_vul ${project_config_prevent_vulnerable_images_from_running_checkbox}
\ ${ret} Get Selected List Value ${project_config_severity_select}
\ @{severity}= Get Value From Json ${json} $.projects[?(@.name=${project})].configuration.severity
\ Should Contain ${ret} @{severity}[0]
\ Navigate To Projects
FOR ${project} IN @{project}
@{out_has_image}= Get Value From Json ${json} $.projects[?(@.name=${project})].has_image
${has_image} Set Variable If @{out_has_image}[0] == ${true} ${true} ${false}
Go Into Project ${project} has_image=${has_image}
Switch To Project Configuration
Verify Checkbox ${json} $.projects[?(@.name=${project})].configuration.public ${project_config_public_checkbox}
Verify Checkbox ${json} $.projects[?(@.name=${project})].configuration.enable_content_trust ${project_config_content_trust_checkbox}
Verify Checkbox ${json} $.projects[?(@.name=${project})].configuration.auto_scan ${project_config_scan_images_on_push_checkbox}
Verify Checkbox ${json} $.projects[?(@.name=${project})].configuration.prevent_vul ${project_config_prevent_vulnerable_images_from_running_checkbox}
${ret} Get Selected List Value ${project_config_severity_select}
@{severity}= Get Value From Json ${json} $.projects[?(@.name=${project})].configuration.severity
Should Contain ${ret} @{severity}[0]
Navigate To Projects
END
Close Browser
Verify Checkbox
@ -77,8 +82,9 @@ Verify Checkbox
Loop Image Repo
[Arguments] @{repo}
:For ${repo} In @{repo}
\ Page Should Contain ${repo}
FOR ${repo} IN @{repo}
Page Should Contain ${repo}
END
Verify Member Exist
[Arguments] ${json}
@ -86,14 +92,15 @@ Verify Member Exist
@{project}= Get Value From Json ${json} $.projects.[*].name
Init Chrome Driver
Sign In Harbor ${HARBOR_URL} ${HARBOR_ADMIN} ${HARBOR_PASSWORD}
:For ${project} In @{project}
\ @{out_has_image}= Get Value From Json ${json} $.projects[?(@.name=${project})].has_image
\ ${has_image} Set Variable If @{out_has_image}[0] == ${true} ${true} ${false}
\ Go Into Project ${project} has_image=${has_image}
\ Switch To Member
\ @{members}= Get Value From Json ${json} $.projects[?(@.name=${project})].member..name
\ Loop Member @{members}
\ Navigate To Projects
FOR ${project} IN @{project}
@{out_has_image}= Get Value From Json ${json} $.projects[?(@.name=${project})].has_image
${has_image} Set Variable If @{out_has_image}[0] == ${true} ${true} ${false}
Go Into Project ${project} has_image=${has_image}
Switch To Member
@{members}= Get Value From Json ${json} $.projects[?(@.name=${project})].member..name
Loop Member @{members}
Navigate To Projects
END
Close Browser
Verify Webhook
@ -102,24 +109,25 @@ Verify Webhook
@{project}= Get Value From Json ${json} $.projects.[*].name
Init Chrome Driver
Sign In Harbor ${HARBOR_URL} ${HARBOR_ADMIN} ${HARBOR_PASSWORD}
:For ${project} In @{project}
\ @{out_has_image}= Get Value From Json ${json} $.projects[?(@.name=${project})].has_image
\ ${has_image} Set Variable If @{out_has_image}[0] == ${true} ${true} ${false}
\ Go Into Project ${project} has_image=${has_image}
\ Switch To Project Webhooks
\ @{enabled}= Get Value From Json ${json} $.projects[?(@.name=${project})].webhook.enabled
\ ${enable_count} Get Matching Xpath Count xpath=//span[contains(.,'Enabled')]
\ ${disable_count} Get Matching Xpath Count xpath=//span[contains(.,'Disabled')]
\ Log To Console '@{enabled}[0]'
\ Log To Console '${true}'
\ Run Keyword If '@{enabled}[0]' == '${true}' Page Should Contain Enabled
\ ... ELSE Page Should Contain Disabled
\ @{address}= Get Value From Json ${json} $.projects[?(@.name=${project})].webhook.address
\ Log To Console '@{address}[0]'
\ Page Should Contain @{address}[0]
\ Page Should Contain policy
\ Page Should Contain http
\ Navigate To Projects
FOR ${project} IN @{project}
@{out_has_image}= Get Value From Json ${json} $.projects[?(@.name=${project})].has_image
${has_image} Set Variable If @{out_has_image}[0] == ${true} ${true} ${false}
Go Into Project ${project} has_image=${has_image}
Switch To Project Webhooks
${enabled}= Get Value From Json ${json} $.projects[?(@.name=${project})].webhook.enabled
${enable_count} Get Element Count xpath=//span[contains(.,'Enabled')]
${disable_count} Get Element Count xpath=//span[contains(.,'Disabled')]
Log To Console '${enabled}[0]'
Log To Console '${true}'
Run Keyword If '${enabled}[0]' == '${true}' Page Should Contain Enabled
... ELSE Page Should Contain Disabled
${address}= Get Value From Json ${json} $.projects[?(@.name=${project})].webhook.address
Log To Console '${address}[0]'
Page Should Contain ${address}[0]
Page Should Contain policy
Page Should Contain http
Navigate To Projects
END
Close Browser
Verify Tag Retention Rule
@ -128,22 +136,23 @@ Verify Tag Retention Rule
@{project}= Get Value From Json ${json} $.projects.[*].name
Init Chrome Driver
Sign In Harbor ${HARBOR_URL} ${HARBOR_ADMIN} ${HARBOR_PASSWORD}
:For ${project} In @{project}
\ @{out_has_image}= Get Value From Json ${json} $.projects[?(@.name=${project})].has_image
\ ${has_image} Set Variable If @{out_has_image}[0] == ${true} ${true} ${false}
\ Go Into Project ${project} has_image=${has_image}
\ Switch To Tag Retention
\ ${actions_count}= Set Variable 8
\ @{repository_patten}= Get Value From Json ${json} $.projects[?(@.name=${project})].tag_retention_rule.repository_patten
\ @{tag_decoration}= Get Value From Json ${json} $.projects[?(@.name=${project})].tag_retention_rule.tag_decoration
\ @{latestPushedK}= Get Value From Json ${json} $.projects[?(@.name=${project})].tag_retention_rule.latestPushedK
\ @{cron}= Get Value From Json ${json} $.projects[?(@.name=${project})].tag_retention_rule.cron
\ Log To Console '@{repository_patten}[0]'
\ Page Should Contain @{repository_patten}[0]
\ Page Should Contain @{tag_decoration}[0]
\ Page Should Contain @{latestPushedK}[0]
\ Page Should Contain @{cron}[0]
\ Navigate To Projects
FOR ${project} IN @{project}
${out_has_image}= Get Value From Json ${json} $.projects[?(@.name=${project})].has_image
${has_image} Set Variable If ${out_has_image}[0] == ${true} ${true} ${false}
Go Into Project ${project} has_image=${has_image}
Switch To Tag Retention
${actions_count}= Set Variable 8
${repository_patten}= Get Value From Json ${json} $.projects[?(@.name=${project})].tag_retention_rule.repository_patten
${tag_decoration}= Get Value From Json ${json} $.projects[?(@.name=${project})].tag_retention_rule.tag_decoration
${latestPushedK}= Get Value From Json ${json} $.projects[?(@.name=${project})].tag_retention_rule.latestPushedK_verify
${cron}= Get Value From Json ${json} $.projects[?(@.name=${project})].tag_retention_rule.cron
Log To Console '${repository_patten}[0]'
Page Should Contain ${repository_patten}[0]
Page Should Contain ${tag_decoration}[0]
Page Should Contain ${latestPushedK}[0]
Page Should Contain ${cron}[0]
Navigate To Projects
END
Close Browser
Verify Tag Immutability Rule
@ -152,27 +161,29 @@ Verify Tag Immutability Rule
@{project}= Get Value From Json ${json} $.projects.[*].name
Init Chrome Driver
Sign In Harbor ${HARBOR_URL} ${HARBOR_ADMIN} ${HARBOR_PASSWORD}
:For ${project} In @{project}
\ @{out_has_image}= Get Value From Json ${json} $.projects[?(@.name=${project})].has_image
\ ${has_image} Set Variable If @{out_has_image}[0] == ${true} ${true} ${false}
\ Go Into Project ${project} has_image=${has_image}
\ Switch To Tag Immutability
\ @{repo_decoration}= Get Value From Json ${json} $.projects[?(@.name=${project})].tag_immutability_rule.repo_decoration
\ @{tag_decoration}= Get Value From Json ${json} $.projects[?(@.name=${project})].tag_immutability_rule.tag_decoration
\ @{repo_pattern}= Get Value From Json ${json} $.projects[?(@.name=${project})].tag_immutability_rule.repo_pattern
\ @{tag_pattern}= Get Value From Json ${json} $.projects[?(@.name=${project})].tag_immutability_rule.tag_pattern
\ Log To Console '@{repo_decoration}[0]'
#\ Page Should Contain @{repo_decoration}[0]
#\ Page Should Contain @{tag_decoration}[0]
\ Page Should Contain @{repo_pattern}[0]
\ Page Should Contain @{tag_pattern}[0]
\ Navigate To Projects
FOR ${project} IN @{project}
@{out_has_image}= Get Value From Json ${json} $.projects[?(@.name=${project})].has_image
${has_image} Set Variable If @{out_has_image}[0] == ${true} ${true} ${false}
Go Into Project ${project} has_image=${has_image}
Switch To Tag Immutability
@{repo_decoration}= Get Value From Json ${json} $.projects[?(@.name=${project})].tag_immutability_rule.repo_decoration
@{tag_decoration}= Get Value From Json ${json} $.projects[?(@.name=${project})].tag_immutability_rule.tag_decoration
@{repo_pattern}= Get Value From Json ${json} $.projects[?(@.name=${project})].tag_immutability_rule.repo_pattern
@{tag_pattern}= Get Value From Json ${json} $.projects[?(@.name=${project})].tag_immutability_rule.tag_pattern
Log To Console '@{repo_decoration}[0]'
#Page Should Contain @{repo_decoration}[0]
#Page Should Contain @{tag_decoration}[0]
Page Should Contain @{repo_pattern}[0]
Page Should Contain @{tag_pattern}[0]
Navigate To Projects
END
Close Browser
Loop Member
[Arguments] @{members}
:For ${member} In @{members}
\ Page Should Contain ${member}
FOR ${member} IN @{members}
Page Should Contain ${member}
END
Verify Robot Account Exist
[Arguments] ${json}
@ -180,30 +191,33 @@ Verify Robot Account Exist
@{project}= Get Value From Json ${json} $.projects.[*].name
Init Chrome Driver
Sign In Harbor ${HARBOR_URL} ${HARBOR_ADMIN} ${HARBOR_PASSWORD}
:For ${project} In @{project}
\ @{out_has_image}= Get Value From Json ${json} $.projects[?(@.name=${project})].has_image
\ ${has_image} Set Variable If @{out_has_image}[0] == ${true} ${true} ${false}
\ Go Into Project ${project} has_image=${has_image}
\ Switch To Project Robot Account
\ @{robot_accounts}= Get Value From Json ${json} $.projects[?(@.name=${project})].robot_account..name
\ Loop Verify Robot Account @{robot_accounts}
\ Navigate To Projects
FOR ${project} IN @{project}
@{out_has_image}= Get Value From Json ${json} $.projects[?(@.name=${project})].has_image
${has_image} Set Variable If @{out_has_image}[0] == ${true} ${true} ${false}
Go Into Project ${project} has_image=${has_image}
Switch To Project Robot Account
@{robot_accounts}= Get Value From Json ${json} $.projects[?(@.name=${project})].robot_account..name
Loop Verify Robot Account @{robot_accounts}
Navigate To Projects
END
Close Browser
Loop Verify Robot Account
[Arguments] @{robot_accounts}
:For ${robot_account} In @{robot_accounts}
\ Page Should Contain ${robot_account}
FOR ${robot_account} IN @{robot_accounts}
Page Should Contain ${robot_account}
END
Verify User System Admin Role
[Arguments] ${json}
Log To Console "Verify User System Admin Role..."
@{user}= Get Value From Json ${json} $.admin..name
Init Chrome Driver
:FOR ${user} IN @{user}
\ Sign In Harbor ${HARBOR_URL} ${user} ${HARBOR_PASSWORD}
\ Page Should Contain Administration
\ Logout Harbor
FOR ${user} IN @{user}
Sign In Harbor ${HARBOR_URL} ${user} ${HARBOR_PASSWORD}
Page Should Contain Administration
Logout Harbor
END
Close Browser
Verify System Label
@ -214,25 +228,28 @@ Verify System Label
Sign In Harbor ${HARBOR_URL} ${HARBOR_ADMIN} ${HARBOR_PASSWORD}
Switch To Configure
Switch To System Labels
:For ${label} In @{label}
\ Page Should Contain ${label}
FOR ${label} IN @{label}
Page Should Contain ${label}
END
Close Browser
Verify Project Label
[Arguments] ${json}
Log To Console "Verify Project Label..."
@{project}= Get Value From Json ${json} $.peoject.[*].name
Init Chrome Driver
Sign In Harbor ${HARBOR_URL} ${HARBOR_ADMIN} ${HARBOR_PASSWORD}
:For ${project} In @{project}
\ @{out_has_image}= Get Value From Json ${json} $.projects[?(@.name=${project})].has_image
\ ${has_image} Set Variable If @{out_has_image}[0] == ${true} ${true} ${false}
\ Go Into Project ${project} has_image=${has_image}
\ Switch To Project Label
\ @{projectlabel}= Get Value From Json ${json} $.projects[?(@.name=${project})]..labels..name
\ :For ${label} In @{label}
\ \ Page Should Contain ${projectlabel}
\ Navigate To Projects
[Arguments] ${json}
Log To Console "Verify Project Label..."
@{project}= Get Value From Json ${json} $.peoject.[*].name
Init Chrome Driver
Sign In Harbor ${HARBOR_URL} ${HARBOR_ADMIN} ${HARBOR_PASSWORD}
FOR ${project} IN @{project}
@{out_has_image}= Get Value From Json ${json} $.projects[?(@.name=${project})].has_image
${has_image} Set Variable If @{out_has_image}[0] == ${true} ${true} ${false}
Go Into Project ${project} has_image=${has_image}
Switch To Project Label
@{projectlabel}= Get Value From Json ${json} $.projects[?(@.name=${project})]..labels..name
FOR ${label} IN @{label}
Page Should Contain ${projectlabel}
END
Navigate To Projects
END
Close Browser
Verify Endpoint
@ -242,8 +259,9 @@ Verify Endpoint
Init Chrome Driver
Sign In Harbor ${HARBOR_URL} ${HARBOR_ADMIN} ${HARBOR_PASSWORD}
Switch To Registries
:For ${endpoint} In @{endpoint}
\ Page Should Contain ${endpoint}
FOR ${endpoint} IN @{endpoint}
Page Should Contain ${endpoint}
END
Close Browser
Verify Replicationrule
@ -251,63 +269,65 @@ Verify Replicationrule
Log To Console "Verify Replicationrule..."
@{replicationrules}= Get Value From Json ${json} $.replicationrule.[*].rulename
@{endpoints}= Get Value From Json ${json} $.endpoint.[*].name
: FOR ${replicationrule} IN @{replicationrules}
\ Init Chrome Driver
\ Log To Console -----replicationrule-----"${replicationrule}"------------
\ Sign In Harbor ${HARBOR_URL} ${HARBOR_ADMIN} ${HARBOR_PASSWORD}
\ Switch To Replication Manage
\ Select Rule And Click Edit Button ${replicationrule}
\ @{is_src_registry}= Get Value From Json ${json} $.replicationrule[?(@.rulename=${replicationrule})].is_src_registry
\ @{trigger_type}= Get Value From Json ${json} $.replicationrule[?(@.rulename=${replicationrule})].trigger_type
\ @{name_filters}= Get Value From Json ${json} $.replicationrule[?(@.rulename=${replicationrule})].name_filters
\ @{tag_filters}= Get Value From Json ${json} $.replicationrule[?(@.rulename=${replicationrule})].tag_filters
\ @{dest_namespace}= Get Value From Json ${json} $.replicationrule[?(@.rulename=${replicationrule})].dest_namespace
\ @{cron}= Get Value From Json ${json} $.replicationrule[?(@.rulename=${replicationrule})].cron
\ @{is_src_registry}= Get Value From Json ${json} $.replicationrule[?(@.rulename=${replicationrule})].is_src_registry
\ Log To Console -----is_src_registry-----@{is_src_registry}[0]------------
\ @{endpoint}= Get Value From Json ${json} $.replicationrule[?(@.rulename=${replicationrule})].endpoint
\ Log To Console -----endpoint-----@{endpoint}------------
\ ${endpoint0}= Set Variable @{endpoint}[0]
\ Log To Console -----endpoint0-----${endpoint0}------------
\ @{endpoint_type}= Get Value From Json ${json} $.endpoint[?(@.name=${endpoint0})].type
\ Retry Textfield Value Should Be ${source_project} @{name_filters}[0]
\ Retry Textfield Value Should Be ${filter_tag} @{tag_filters}[0]
\ Retry Textfield Value Should Be ${rule_name_input} ${replicationrule}
\ Retry Textfield Value Should Be ${dest_namespace_xpath} @{dest_namespace}[0]
\ Log To Console -----endpoint_type-----@{endpoint_type}[0]------------
\ ${registry}= Set Variable If "@{endpoint_type}[0]"=="harbor" ${endpoint0}-https://${IP} ${endpoint0}-https://hub.docker.com
\ Log To Console -------registry---${registry}------------
\ Run Keyword If '@{is_src_registry}[0]' == '${true}' Retry List Selection Should Be ${src_registry_dropdown_list} ${registry}
\ ... ELSE Retry List Selection Should Be ${dest_registry_dropdown_list} ${registry}
\ #\ Retry List Selection Should Be ${rule_resource_selector} ${resource_type}
\ Retry List Selection Should Be ${rule_trigger_select} @{trigger_type}[0]
\ Run Keyword If '@{trigger_type}[0]' == 'scheduled' Log To Console ----------@{trigger_type}[0]------------
\ Run Keyword If '@{trigger_type}[0]' == 'scheduled' Retry Textfield Value Should Be ${targetCron_id} @{cron}[0]
FOR ${replicationrule} IN @{replicationrules}
Init Chrome Driver
Log To Console -----replicationrule-----"${replicationrule}"------------
Sign In Harbor ${HARBOR_URL} ${HARBOR_ADMIN} ${HARBOR_PASSWORD}
Switch To Replication Manage
Select Rule And Click Edit Button ${replicationrule}
@{is_src_registry}= Get Value From Json ${json} $.replicationrule[?(@.rulename=${replicationrule})].is_src_registry
@{trigger_type}= Get Value From Json ${json} $.replicationrule[?(@.rulename=${replicationrule})].trigger_type
@{name_filters}= Get Value From Json ${json} $.replicationrule[?(@.rulename=${replicationrule})].name_filters
@{tag_filters}= Get Value From Json ${json} $.replicationrule[?(@.rulename=${replicationrule})].tag_filters
@{dest_namespace}= Get Value From Json ${json} $.replicationrule[?(@.rulename=${replicationrule})].dest_namespace
@{cron}= Get Value From Json ${json} $.replicationrule[?(@.rulename=${replicationrule})].cron
@{is_src_registry}= Get Value From Json ${json} $.replicationrule[?(@.rulename=${replicationrule})].is_src_registry
Log To Console -----is_src_registry-----@{is_src_registry}[0]------------
@{endpoint}= Get Value From Json ${json} $.replicationrule[?(@.rulename=${replicationrule})].endpoint
Log To Console -----endpoint-----@{endpoint}------------
${endpoint0}= Set Variable @{endpoint}[0]
Log To Console -----endpoint0-----${endpoint0}------------
@{endpoint_type}= Get Value From Json ${json} $.endpoint[?(@.name=${endpoint0})].type
Retry Textfield Value Should Be ${filter_name_id} @{name_filters}[0]
Retry Textfield Value Should Be ${filter_tag_id} @{tag_filters}[0]
Retry Textfield Value Should Be ${rule_name_input} ${replicationrule}
Retry Textfield Value Should Be ${dest_namespace_xpath} @{dest_namespace}[0]
Log To Console -----endpoint_type-----@{endpoint_type}[0]------------
${registry}= Set Variable If "@{endpoint_type}[0]"=="harbor" ${endpoint0}-https://${IP} ${endpoint0}-https://hub.docker.com
Log To Console -------registry---${registry}------------
Run Keyword If '@{is_src_registry}[0]' == '${true}' Retry List Selection Should Be ${src_registry_dropdown_list} ${registry}
... ELSE Retry List Selection Should Be ${dest_registry_dropdown_list} ${registry}
#Retry List Selection Should Be ${rule_resource_selector} ${resource_type}
Retry List Selection Should Be ${rule_trigger_select} @{trigger_type}[0]
Run Keyword If '@{trigger_type}[0]' == 'scheduled' Log To Console ----------@{trigger_type}[0]------------
Run Keyword If '@{trigger_type}[0]' == 'scheduled' Retry Textfield Value Should Be ${targetCron_id} @{cron}[0]
END
Close Browser
Verify Project Setting
[Arguments] ${json}
Log To Console "Verify Project Setting..."
@{projects}= Get Value From Json ${json} $.projects.[*].name
:For ${project} In @{Projects}
\ ${public}= Get Value From Json ${json} $.projects[?(@.name=${project})].accesslevel
\ ${contenttrust}= Get Value From Json ${json} $.projects[?(@.name=${project})]..enable_content_trust
\ ${preventrunning}= Get Value From Json ${json} $.projects[?(@.name=${project})]..prevent_vulnerable_images_from_running
\ ${scanonpush}= Get Value From Json ${json} $.projects[?(@.name=${project})]..automatically_scan_images_on_push
\ Init Chrome Driver
\ Sign In Harbor ${HARBOR_URL} ${HARBOR_ADMIN} ${HARBOR_PASSWORD}
\ @{out_has_image}= Get Value From Json ${json} $.projects[?(@.name=${project})].has_image
\ ${has_image} Set Variable If @{out_has_image}[0] == ${true} ${true} ${false}
\ Go Into Project ${project} has_image=${has_image}
\ Goto Project Config
\ Run Keyword If ${public} == "public" Checkbox Should Be Checked //clr-checkbox-wrapper[@name='public']//label
\ Run Keyword If ${contenttrust} == "true" Checkbox Should Be Checked //clr-checkbox-wrapper[@name='content-trust']//label
\ Run Keyword If ${contenttrust} == "false" Checkbox Should Not Be Checked //clr-checkbox-wrapper[@name='content-trust']//label
\ Run Keyword If ${preventrunning} == "true" Checkbox Should Be Checked //*[@id='prevent-vulenrability-image']//clr-checkbox-wrapper//label
\ Run Keyword If ${preventrunning} == "false" Checkbox Should Not Be Checked //*[@id='prevent-vulenrability-image']//clr-checkbox-wrapper//label
\ Run Keyword If ${scanonpush} == "true" Checkbox Should Be Checked //clr-checkbox-wrapper[@id='scan-image-on-push-wrapper']//input
\ Run Keyword If ${scanonpush} == "true" Checkbox Should Not Be Checked //clr-checkbox-wrapper[@id='scan-image-on-push-wrapper']//input
\ Close Browser
FOR ${project} IN @{Projects}
${public}= Get Value From Json ${json} $.projects[?(@.name=${project})].accesslevel
${contenttrust}= Get Value From Json ${json} $.projects[?(@.name=${project})]..enable_content_trust
${preventrunning}= Get Value From Json ${json} $.projects[?(@.name=${project})]..prevent_vulnerable_images_from_running
${scanonpush}= Get Value From Json ${json} $.projects[?(@.name=${project})]..automatically_scan_images_on_push
Init Chrome Driver
Sign In Harbor ${HARBOR_URL} ${HARBOR_ADMIN} ${HARBOR_PASSWORD}
@{out_has_image}= Get Value From Json ${json} $.projects[?(@.name=${project})].has_image
${has_image} Set Variable If @{out_has_image}[0] == ${true} ${true} ${false}
Go Into Project ${project} has_image=${has_image}
Goto Project Config
Run Keyword If ${public} == "public" Checkbox Should Be Checked //clr-checkbox-wrapper[@name='public']//label
Run Keyword If ${contenttrust} == "true" Checkbox Should Be Checked //clr-checkbox-wrapper[@name='content-trust']//label
Run Keyword If ${contenttrust} == "false" Checkbox Should Not Be Checked //clr-checkbox-wrapper[@name='content-trust']//label
Run Keyword If ${preventrunning} == "true" Checkbox Should Be Checked //*[@id='prevent-vulenrability-image']//clr-checkbox-wrapper//label
Run Keyword If ${preventrunning} == "false" Checkbox Should Not Be Checked //*[@id='prevent-vulenrability-image']//clr-checkbox-wrapper//label
Run Keyword If ${scanonpush} == "true" Checkbox Should Be Checked //clr-checkbox-wrapper[@id='scan-image-on-push-wrapper']//input
Run Keyword If ${scanonpush} == "true" Checkbox Should Not Be Checked //clr-checkbox-wrapper[@id='scan-image-on-push-wrapper']//input
Close Browser
END
Verify Interrogation Services
[Arguments] ${json}
@ -358,23 +378,25 @@ Verify Project-level Whitelist
@{project}= Get Value From Json ${json} $.projects.[*].name
Init Chrome Driver
Sign In Harbor ${HARBOR_URL} ${HARBOR_ADMIN} ${HARBOR_PASSWORD}
:FOR ${project} IN @{project}
\ @{out_has_image}= Get Value From Json ${json} $.projects[?(@.name=${project})].has_image
\ ${has_image} Set Variable If @{out_has_image}[0] == ${true} ${true} ${false}
\ Go Into Project ${project} has_image=${has_image}
\ Switch To Project Configuration
\ @{is_reuse_sys_cve_whitelist}= Get Value From Json ${json} $.projects[?(@.name=${project})].configuration.reuse_sys_cve_whitelist
\ Run Keyword If "@{is_reuse_sys_cve_whitelist}[0]" == "true" Retry Wait Element Should Be Disabled ${project_config_project_wl_add_btn}
\ ... ELSE Retry Wait Element ${project_config_project_wl_add_btn}
\ @{cve_ids}= Get Value From Json ${json} $.projects[?(@.name=${project})].configuration.cve
\ Loop Verifiy CVE_IDs @{cve_ids}
\ Navigate To Projects
FOR ${project} IN @{project}
@{out_has_image}= Get Value From Json ${json} $.projects[?(@.name=${project})].has_image
${has_image} Set Variable If @{out_has_image}[0] == ${true} ${true} ${false}
Go Into Project ${project} has_image=${has_image}
Switch To Project Configuration
@{is_reuse_sys_cve_whitelist}= Get Value From Json ${json} $.projects[?(@.name=${project})].configuration.reuse_sys_cve_whitelist
Run Keyword If "@{is_reuse_sys_cve_whitelist}[0]" == "true" Retry Wait Element Should Be Disabled ${project_config_project_wl_add_btn}
... ELSE Retry Wait Element ${project_config_project_wl_add_btn}
@{cve_ids}= Get Value From Json ${json} $.projects[?(@.name=${project})].configuration.cve
Loop Verifiy CVE_IDs @{cve_ids}
Navigate To Projects
END
Close Browser
Loop Verifiy CVE_IDs
[Arguments] @{cve_ids}
:For ${cve_id} In @{cve_ids}
\ Page Should Contain ${cve_id}
FOR ${cve_id} IN @{cve_ids}
Page Should Contain ${cve_id}
END
Verify System Setting Whitelist
[Arguments] ${json}

View File

@ -14,7 +14,7 @@
*** Settings ***
Documentation This resource provides any keywords related to the Harbor private registry appliance
Library Selenium2Library
Library SeleniumLibrary
Library OperatingSystem
*** Variables ***
@ -26,7 +26,7 @@ Install Harbor to Test Server
Sleep 5s
${rc} ${output}= Run And Return Rc And Output docker ps
Should Be Equal As Integers ${rc} 0
Log To Console \n${output}
Log To Console ${output}
Log To Console \nconfig harbor cfg
Config Harbor cfg http_proxy=https
Prepare Cert
@ -34,7 +34,7 @@ Install Harbor to Test Server
Compile and Up Harbor With Source Code
${rc} ${output}= Run And Return Rc And Output docker ps
Should Be Equal As Integers ${rc} 0
Log To Console \n${output}
Log To Console ${output}
Generate Certificate Authority For Chrome
Up Harbor
@ -55,7 +55,7 @@ Package Harbor Offline
[Arguments] ${with_notary}=true ${with_clair}=true ${with_chartmuseum}=true ${with_trivy}=true
Log To Console \nStart Docker Daemon
Start Docker Daemon Locally
Log To Console \n\nmake package_offline GOBUILDTAGS="include_oss include_gcs" BASEIMAGETAG=%{Harbor_Build_Base_Tag} NPM_REGISTRY=%{NPM_REGISTRY} VERSIONTAG=%{Harbor_Assets_Version} PKGVERSIONTAG=%{Harbor_Package_Version} NOTARYFLAG=${with_notary} CLAIRFLAG=${with_clair} CHARTFLAG=${with_chartmuseum} TRIVYFLAG=${with_trivy} HTTPPROXY=
Log To Console make package_offline GOBUILDTAGS="include_oss include_gcs" BASEIMAGETAG=%{Harbor_Build_Base_Tag} NPM_REGISTRY=%{NPM_REGISTRY} VERSIONTAG=%{Harbor_Assets_Version} PKGVERSIONTAG=%{Harbor_Package_Version} NOTARYFLAG=${with_notary} CLAIRFLAG=${with_clair} CHARTFLAG=${with_chartmuseum} TRIVYFLAG=${with_trivy} HTTPPROXY=
${rc} ${output}= Run And Return Rc And Output make package_offline GOBUILDTAGS="include_oss include_gcs" BASEIMAGETAG=%{Harbor_Build_Base_Tag} NPM_REGISTRY=%{NPM_REGISTRY} VERSIONTAG=%{Harbor_Assets_Version} PKGVERSIONTAG=%{Harbor_Package_Version} NOTARYFLAG=${with_notary} CLAIRFLAG=${with_clair} CHARTFLAG=${with_chartmuseum} TRIVYFLAG=${with_trivy} HTTPPROXY=
Log To Console ${rc}
Log To Console ${output}
@ -148,14 +148,15 @@ Compile and Up Harbor With Source Code
Wait for Harbor Ready
[Arguments] ${protocol} ${HARBOR_IP}
Log To Console Waiting for Harbor to Come Up...
:FOR ${i} IN RANGE 20
\ ${out}= Run curl -k ${protocol}://${HARBOR_IP}
\ Log ${out}
\ ${status}= Run Keyword And Return Status Should Not Contain ${out} 502 Bad Gateway
\ ${status}= Run Keyword If ${status} Run Keyword And Return Status Should Not Contain ${out} Connection refused
\ ${status}= Run Keyword If ${status} Run Keyword And Return Status Should Contain ${out} <title>Harbor</title>
\ Return From Keyword If ${status} ${HARBOR_IP}
\ Sleep 30s
FOR ${i} IN RANGE 20
${out}= Run curl -k ${protocol}://${HARBOR_IP}
Log ${out}
${status}= Run Keyword And Return Status Should Not Contain ${out} 502 Bad Gateway
${status}= Run Keyword If ${status} Run Keyword And Return Status Should Not Contain ${out} Connection refused
${status}= Run Keyword If ${status} Run Keyword And Return Status Should Contain ${out} <title>Harbor</title>
Return From Keyword If ${status} ${HARBOR_IP}
Sleep 30s
END
Fail Harbor failed to come up properly!
Get Harbor Version

View File

@ -37,12 +37,13 @@ Init Chrome Driver
Call Method ${chrome options} add_argument --window-size\=1600,900
${chrome options.binary_location} Set Variable /usr/bin/google-chrome
#Create Webdriver Chrome Chrome_headless chrome_options=${chrome options} desired_capabilities=${capabilities}
:For ${n} IN RANGE 1 6
\ Log To Console Trying Create Webdriver ${n} times ...
\ ${out} Run Keyword And Ignore Error Create Webdriver Chrome Chrome_headless chrome_options=${chrome options} desired_capabilities=${capabilities}
\ Log To Console Return value is ${out[0]}
\ Exit For Loop If '${out[0]}'=='PASS'
\ Sleep 2
FOR ${n} IN RANGE 1 6
Log To Console Trying Create Webdriver ${n} times ...
${out} Run Keyword And Ignore Error Create Webdriver Chrome Chrome_headless chrome_options=${chrome options} desired_capabilities=${capabilities}
Log To Console Return value is ${out[0]}
Exit For Loop If '${out[0]}'=='PASS'
Sleep 2
END
Run Keyword If '${out[0]}'=='FAIL' Capture Page Screenshot
Should Be Equal As Strings '${out[0]}' 'PASS'
Sleep 5

View File

@ -186,7 +186,7 @@ Manage Project Member Without Sign In Harbor
[Arguments] ${sign_in_user} ${sign_in_pwd} ${test_user1}=user005 ${test_user2}=user006 ${is_oidc_mode}=${false}
${d}= Get current Date result_format=%m%s
Create An New Project And Go Into Project project${d}
Push image ip=${ip} user=${sign_in_user} pwd=${sign_in_pwd} project=project${d} image=hello-world
Push image ${ip} ${sign_in_user} ${sign_in_pwd} project${d} hello-world
Logout Harbor
User Should Not Be A Member Of Project ${test_user1} ${sign_in_pwd} project${d} is_oidc_mode=${is_oidc_mode}
@ -200,7 +200,7 @@ Manage Project Member Without Sign In Harbor
User Should Be Master ${test_user1} ${sign_in_pwd} project${d} is_oidc_mode=${is_oidc_mode}
Manage Project Member ${sign_in_user} ${sign_in_pwd} project${d} ${test_user1} Remove is_oidc_mode=${is_oidc_mode}
User Should Not Be A Member Of Project ${test_user1} ${sign_in_pwd} project${d} is_oidc_mode=${is_oidc_mode}
Push image ip=${ip} user=${sign_in_user} pwd=${sign_in_pwd} project=project${d} image=hello-world
Push image ${ip} ${sign_in_user} ${sign_in_pwd} project${d} hello-world
User Should Be Guest ${test_user2} ${sign_in_pwd} project${d} is_oidc_mode=${is_oidc_mode}
Helm CLI Push Without Sign In Harbor
@ -254,7 +254,7 @@ Body Of Verfiy System Level CVE Whitelist
# Add Items To System CVE Whitelist CVE-2019-18276
Add Items To System CVE Whitelist ${single_cve}
Pull Image ${ip} ${signin_user} ${signin_pwd} project${d} ${image} tag=${sha256}
Delete Top Item In System CVE Whitelist count=6
Delete Top Item In System CVE Whitelist count=16
Cannot Pull Image ${ip} ${signin_user} ${signin_pwd} project${d} ${image} tag=${sha256} err_msg=cannot be pulled due to configured policy
Close Browser
@ -315,3 +315,31 @@ Body Of Verfiy Project Level CVE Whitelist By Quick Way of Add System
Add System CVE Whitelist to Project CVE Whitelist By Add System Button Click
Pull Image ${ip} ${signin_user} ${signin_pwd} project${d} ${image} tag=${sha256}
Close Browser
Body Of Replication Of Push Images to Registry Triggered By Event
[Arguments] ${provider} ${endpoint} ${username} ${pwd} ${dest_namespace}
Init Chrome Driver
${d}= Get Current Date result_format=%m%s
${sha256}= Set Variable 0e67625224c1da47cb3270e7a861a83e332f708d3d89dde0cbed432c94824d9a
${image}= Set Variable test_push_repli
${tag1}= Set Variable v1.1.0
@{tags} Create List ${tag1}
#login source
Sign In Harbor ${HARBOR_URL} ${HARBOR_ADMIN} ${HARBOR_PASSWORD}
Create An New Project And Go Into Project project${d}
Switch To Registries
Create A New Endpoint ${provider} e${d} ${endpoint} ${username} ${pwd} Y
Switch To Replication Manage
Create A Rule With Existing Endpoint rule${d} push project${d}/* image e${d} ${dest_namespace} mode=Event Based del_remote=${true}
Push Special Image To Project project${d} ${ip} ${HARBOR_ADMIN} ${HARBOR_PASSWORD} ${image} tags=@{tags} size=12
Filter Replication Rule rule${d}
Select Rule rule${d}
Run Keyword If '${provider}'=='docker-hub' Docker Image Can Be Pulled ${dest_namespace}/${image}:${tag1} times=3
Executions Result Count Should Be Succeeded event_based 1
Go Into Project project${d}
Delete Repo project${d}
Run Keyword If '${provider}'=='docker-hub' Docker Image Can Not Be Pulled ${dest_namespace}/${image}:${tag1}
Switch To Replication Manage
Filter Replication Rule rule${d}
Select Rule rule${d}
Executions Result Count Should Be Succeeded event_based 2

View File

@ -20,7 +20,7 @@ Library requests
Library Process
Library SSHLibrary 1 minute
Library DateTime
Library Selenium2Library 60 10
Library SeleniumLibrary 60 10
Library JSONLibrary
Resource Nimbus-Util.robot
Resource Vsphere-Util.robot
@ -206,16 +206,18 @@ Text Input
Clear Field Of Characters
[Arguments] ${field} ${character count}
[Documentation] This keyword pushes the delete key (ascii: \8) a specified number of times in a specified field.
: FOR ${index} IN RANGE ${character count}
\ Press Keys ${field} \\8
FOR ${index} IN RANGE ${character count}
Press Keys ${field} \\8
END
Wait Unitl Command Success
[Arguments] ${cmd} ${times}=8
:FOR ${n} IN RANGE 1 ${times}
\ Log Trying ${cmd}: ${n} ... console=True
\ ${rc} ${output}= Run And Return Rc And Output ${cmd}
\ Exit For Loop If '${rc}'=='0'
\ Sleep 2
FOR ${n} IN RANGE 1 ${times}
Log Trying ${cmd}: ${n} ... console=True
${rc} ${output}= Run And Return Rc And Output ${cmd}
Exit For Loop If '${rc}'=='0'
Sleep 2
END
Log Command Result is ${output}
Should Be Equal As Strings '${rc}' '0'
[Return] ${output}
@ -229,41 +231,45 @@ Command Should be Failed
Retry Keyword N Times When Error
[Arguments] ${times} ${keyword} @{elements}
:For ${n} IN RANGE 1 ${times}
\ Log To Console Trying ${keyword} elements @{elements} ${n} times ...
\ ${out} Run Keyword And Ignore Error ${keyword} @{elements}
\ Log To Console Return value is ${out} and ${out[0]}
\ Run Keyword If '${keyword}'=='Make Swagger Client' Exit For Loop If '${out[0]}'=='PASS' and '${out[1]}'=='0'
\ ... ELSE Exit For Loop If '${out[0]}'=='PASS'
\ Sleep 10
FOR ${n} IN RANGE 1 ${times}
Log To Console Trying ${keyword} elements @{elements} ${n} times ...
${out} Run Keyword And Ignore Error ${keyword} @{elements}
Log To Console Return value is ${out} and ${out[0]}
Capture Page Screenshot record.png
Run Keyword If '${keyword}'=='Make Swagger Client' Exit For Loop If '${out[0]}'=='PASS' and '${out[1]}'=='0'
... ELSE Exit For Loop If '${out[0]}'=='PASS'
Sleep 10
END
Run Keyword If '${out[0]}'=='FAIL' Capture Page Screenshot
Should Be Equal As Strings '${out[0]}' 'PASS'
[Return] ${out[1]}
Retry Keyword When Return Value Mismatch
[Arguments] ${keyword} ${expected_value} ${count} @{elements}
:For ${n} IN RANGE 1 ${count}
\ Log To Console Trying ${keyword} ${n} times ...
\ ${out} Run Keyword And Ignore Error ${keyword} @{elements}
\ Log To Console Return value is ${out[1]}
\ ${status}= Set Variable If '${out[1]}'=='${expected_value}' 'PASS' 'FAIL'
\ Exit For Loop If '${out[1]}'=='${expected_value}'
\ Sleep 2
FOR ${n} IN RANGE 1 ${count}
Log To Console Trying ${keyword} ${n} times ...
${out} Run Keyword And Ignore Error ${keyword} @{elements}
Log To Console Return value is ${out[1]}
${status}= Set Variable If '${out[1]}'=='${expected_value}' 'PASS' 'FAIL'
Exit For Loop If '${out[1]}'=='${expected_value}'
Sleep 2
END
Run Keyword If ${status}=='FAIL' Capture Page Screenshot
Should Be Equal As Strings ${status} 'PASS'
Retry Double Keywords When Error
[Arguments] ${keyword1} ${element1} ${keyword2} ${element2} ${DoAssert}=${true} ${times}=3
:For ${n} IN RANGE 1 ${times}
\ Log To Console Trying ${keyword1} and ${keyword2} ${n} times ...
\ ${out1} Run Keyword And Ignore Error ${keyword1} ${element1}
\ Capture Page Screenshot
\ Sleep 1
\ ${out2} Run Keyword And Ignore Error ${keyword2} ${element2}
\ Capture Page Screenshot
\ Log To Console Return value is ${out1[0]} ${out2[0]}
\ Exit For Loop If '${out2[0]}'=='PASS'
\ Sleep 1
FOR ${n} IN RANGE 1 ${times}
Log To Console Trying ${keyword1} and ${keyword2} ${n} times ...
${out1} Run Keyword And Ignore Error ${keyword1} ${element1}
Capture Page Screenshot
Sleep 1
${out2} Run Keyword And Ignore Error ${keyword2} ${element2}
Capture Page Screenshot
Log To Console Return value is ${out1[0]} ${out2[0]}
Exit For Loop If '${out2[0]}'=='PASS'
Sleep 1
END
Return From Keyword If ${DoAssert} == ${false} '${out2[0]}'
Should Be Equal As Strings '${out2[0]}' 'PASS'

View File

@ -61,22 +61,24 @@ Reset VM
Wait Until VM Powers On
[Arguments] ${vm} ${vc_host} ${vc_user} ${vc_password}
:FOR ${idx} IN RANGE 0 30
\ ${ret}= Run GOVC_URL=${vc_host} GOVC_USERNAME=${vc_user} GOVC_PASSWORD=${vc_password} GOVC_INSECURE=1 govc vm.info ${vm}
\ Set Test Variable ${out} ${ret}
\ ${status}= Run Keyword And Return Status Should Contain ${out} poweredOn
\ Return From Keyword If ${status}
\ Sleep 1
FOR ${idx} IN RANGE 0 30
${ret}= Run GOVC_URL=${vc_host} GOVC_USERNAME=${vc_user} GOVC_PASSWORD=${vc_password} GOVC_INSECURE=1 govc vm.info ${vm}
Set Test Variable ${out} ${ret}
${status}= Run Keyword And Return Status Should Contain ${out} poweredOn
Return From Keyword If ${status}
Sleep 1
END
Fail VM did not power on within 30 seconds
Wait Until VM Powers Off
[Arguments] ${vm} ${vc_host} ${vc_user} ${vc_password}
:FOR ${idx} IN RANGE 0 30
\ ${ret}= Run GOVC_URL=${vc_host} GOVC_USERNAME=${vc_user} GOVC_PASSWORD=${vc_password} GOVC_INSECURE=1 govc vm.info ${vm}
\ Set Test Variable ${out} ${ret}
\ ${status}= Run Keyword And Return Status Should Contain ${out} poweredOff
\ Return From Keyword If ${status}
\ Sleep 1
FOR ${idx} IN RANGE 0 30
${ret}= Run GOVC_URL=${vc_host} GOVC_USERNAME=${vc_user} GOVC_PASSWORD=${vc_password} GOVC_INSECURE=1 govc vm.info ${vm}
Set Test Variable ${out} ${ret}
${status}= Run Keyword And Return Status Should Contain ${out} poweredOff
Return From Keyword If ${status}
Sleep 1
END
Fail VM did not power off within 30 seconds
Wait Until VM Is Destroyed

View File

@ -1,4 +1,4 @@
#!/usr/local/bin/expect
#!/usr/bin/env expect
set HOST [lindex $argv 0]
set PROJECT [lindex $argv 1]

View File

@ -443,20 +443,20 @@ Test Case - Create An New Project With Quotas Set
Test Case - Project Storage Quotas Dispaly And Control
Init Chrome Driver
${d}= Get Current Date result_format=%m%s
${storage_quota}= Set Variable 330
${storage_quota}= Set Variable 350
${storage_quota_unit}= Set Variable MB
${image_a}= Set Variable redis
${image_b}= Set Variable logstash
${image_a_size}= Set Variable 34.15MB
${image_b_size}= Set Variable 321.03MB
${image_a_ver}= Set Variable donotremove5.0
${image_b_ver}= Set Variable do_not_remove_6.8.3
${image_a}= Set Variable one_layer
${image_b}= Set Variable redis
${image_a_size}= Set Variable 330.83MB
${image_b_size}= Set Variable 34.15MB
${image_a_ver}= Set Variable 1.0
${image_b_ver}= Set Variable donotremove5.0
Sign In Harbor ${HARBOR_URL} ${HARBOR_ADMIN} ${HARBOR_PASSWORD}
Create An New Project And Go Into Project project${d} storage_quota=${storage_quota} storage_quota_unit=${storage_quota_unit}
Push Image With Tag ${ip} ${HARBOR_ADMIN} ${HARBOR_PASSWORD} project${d} ${image_b} tag=${image_b_ver} tag1=${image_b_ver}
${storage_quota_ret}= Get Project Storage Quota Text From Project Quotas List project${d}
Should Be Equal As Strings ${storage_quota_ret} ${image_b_size} of ${storage_quota}${storage_quota_unit}
Cannot Push image ${ip} ${HARBOR_ADMIN} ${HARBOR_PASSWORD} project${d} ${image_a}:${image_a_ver} err_msg=adding 25.8 MiB of storage resource, which when updated to current usage of err_msg_2=MiB will exceed the configured upper limit of 330.0 MiB
Cannot Push image ${ip} ${HARBOR_ADMIN} ${HARBOR_PASSWORD} project${d} ${image_a}:${image_a_ver} err_msg=adding 330.1 MiB of storage resource, which when updated to current usage of err_msg_2=MiB will exceed the configured upper limit of ${storage_quota}.0 MiB
Go Into Project project${d}
Delete Repo project${d}/${image_b}
Push Image With Tag ${ip} ${HARBOR_ADMIN} ${HARBOR_PASSWORD} project${d} ${image_a} tag=${image_a_ver} tag1=${image_a_ver}

View File

@ -30,13 +30,14 @@ Test Case - Garbage Collection
Sign In Harbor ${HARBOR_URL} ${HARBOR_ADMIN} ${HARBOR_PASSWORD}
Create An New Project And Go Into Project project${d}
Push Image ${ip} ${HARBOR_ADMIN} ${HARBOR_PASSWORD} project${d} hello-world
Push Image ${ip} ${HARBOR_ADMIN} ${HARBOR_PASSWORD} project${d} redis
Sleep 2
Go Into Project project${d}
Delete Repo project${d}
Sleep 2
GC Now ${HARBOR_URL} ${HARBOR_ADMIN} ${HARBOR_PASSWORD}
Retry GC Should Be Successful 1 0 blobs marked, 3 blobs and 0 manifests eligible for deletion
Retry GC Should Be Successful 1 8 blobs and 0 manifests eligible for deletion
#Retry GC Should Be Successful 1 The GC job actual frees up 34 MB space
Close Browser
Test Case - GC Untagged Images

View File

@ -75,7 +75,7 @@ Test Case - Generate User CLI Secret
Sign In Harbor With OIDC User ${HARBOR_URL}
Create An New Project And Go Into Project project${d}
${secret_old}= Get Secrete By API ${HARBOR_URL}
Push image ip=${ip} user=${OIDC_USERNAME} pwd=${secret_old} project=project${d} image=${image}
Push image ${ip} ${OIDC_USERNAME} ${secret_old} project${d} ${image}
${secret_new}= Generate And Return Secret ${HARBOR_URL}
Log To Console ${secret_old}
Log To Console ${secret_new}

View File

@ -14,7 +14,7 @@
*** Settings ***
Documentation Harbor BATs
Library ../../apitests/python/library/Harbor.py ${SERVER_CONFIG}
Library ../../apitests/python/library/repository.py
Resource ../../resources/Util.robot
Default Tags Replication
@ -115,7 +115,7 @@ Test Case - Replication Rule Edit
Retry Text Input ${rule_name_input} ${rule_name_new}
Select Source Registry ${endpoint2}
#Source Resource Filter
Retry Text Input ${source_project} project${d}
Retry Text Input ${filter_name_id} project${d}
Select From List By Value ${rule_resource_selector} ${resource_type}
Retry Text Input ${dest_namespace_xpath} ${dest_namespace}
Select Trigger ${mode}
@ -125,7 +125,7 @@ Test Case - Replication Rule Edit
Edit Replication Rule By Name ${rule_name_new}
Retry Textfield Value Should Be ${rule_name_input} ${rule_name_new}
Retry List Selection Should Be ${src_registry_dropdown_list} ${endpoint2}-https://${ip}
Retry Textfield Value Should Be ${source_project} project${d}
Retry Textfield Value Should Be ${filter_name_id} project${d}
Retry Textfield Value Should Be ${dest_namespace_xpath} ${dest_namespace}
Retry List Selection Should Be ${rule_resource_selector} ${resource_type}
Retry List Selection Should Be ${rule_trigger_select} ${mode}
@ -156,7 +156,7 @@ Test Case - Replication Of Pull Images from DockerHub To Self
Switch To Registries
Create A New Endpoint docker-hub e${d} https://hub.docker.com/ danfengliu Aa123456 Y
Switch To Replication Manage
Create A Rule With Existing Endpoint rule${d} pull danfengliu/* image e${d} project${d}
Create A Rule With Existing Endpoint rule${d} pull danfengliu/{cent*,mariadb} image e${d} project${d}
Select Rule And Replicate rule${d}
#In docker-hub, under repository danfengliu, there're only 2 images: centos,mariadb.
Image Should Be Replicated To Project project${d} centos
@ -268,8 +268,18 @@ Test Case - Replication Of Pull Images from Google-GCR To Self
Create A New Endpoint google-gcr e${d} asia.gcr.io ${null} ${gcr_ac_key} Y
Switch To Replication Manage
Create A Rule With Existing Endpoint rule${d} pull eminent-nation-87317/* image e${d} project${d}
Filter Replicatin Rule rule${d}
Filter Replication Rule rule${d}
Select Rule And Replicate rule${d}
Image Should Be Replicated To Project project${d} httpd
Image Should Be Replicated To Project project${d} tomcat
Close Browser
Test Case - Replication Of Push Images to DockerHub Triggered By Event
Body Of Replication Of Push Images to Registry Triggered By Event docker-hub https://hub.docker.com/ danfengliu Aa123456 danfengliu
#Due to issue of delete event replication
#Test Case - Replication Of Push Images to Google-GCR Triggered By Event
#Body Of Replication Of Push Images to Registry Triggered By Event google-gcr gcr.io ${null} ${gcr_ac_key} eminent-nation-87317/harbor-nightly-replication
Test Case - Replication Of Push Images to AWS-ECR Triggered By Event
Body Of Replication Of Push Images to Registry Triggered By Event aws-ecr us-east-2 ${ecr_ac_id} ${ecr_ac_key} harbor-nightly-replication

View File

@ -216,6 +216,7 @@
"repository_patten":"*photon*",
"tag_decoration":"*v1.*",
"latestPushedK":666,
"latestPushedK_verify":"666",
"cron":"0 0 0 1 8 0"
},
"tag_immutability_rule":{
@ -347,6 +348,7 @@
"repository_patten":"*centos*",
"tag_decoration":"*latest",
"latestPushedK":999,
"latestPushedK_verify":"999",
"cron":"0 0 0 1 6 0"
},
"tag_immutability_rule":{

View File

@ -14,7 +14,7 @@ args = parser.parse_args()
url = "https://"+args.endpoint+"/api/"
endpoint_url = "https://"+args.endpoint
print url
print(url)
with open("feature_map.json") as f:
feature_map = json.load(f)
@ -108,7 +108,7 @@ class HarborAPI:
"url":""+endpointurl+""
}
body=dict(body=payload)
print body
print(body)
request(url+"/registries", 'post', **body)
else:
raise Exception(r"Error: Feature {} has no branch {}.".format(sys._getframe().f_code.co_name, branch))
@ -131,8 +131,8 @@ class HarborAPI:
else:
registry = r'"dest_registry": { "id": '+str(targetid)+r'},'
body=dict(body=json.loads(r'{"name":"'+replicationrule["rulename"].encode('utf-8')+r'","dest_namespace":"'+replicationrule["dest_namespace"].encode('utf-8')+r'","deletion": '+str(replicationrule["deletion"]).lower()+r',"enabled": '+str(replicationrule["enabled"]).lower()+r',"override": '+str(replicationrule["override"]).lower()+r',"description": "string",'+ registry + r'"trigger":{"type": "'+replicationrule["trigger_type"]+r'", "trigger_settings":{"cron":"'+replicationrule["cron"]+r'"}},"filters":[ {"type":"name","value":"'+replicationrule["name_filters"]+r'"},{"type":"tag","value":"'+replicationrule["tag_filters"]+r'"}]}'))
print body
body=dict(body=json.loads(r'{"name":"'+replicationrule["rulename"]+r'","dest_namespace":"'+replicationrule["dest_namespace"]+r'","deletion": '+str(replicationrule["deletion"]).lower()+r',"enabled": '+str(replicationrule["enabled"]).lower()+r',"override": '+str(replicationrule["override"]).lower()+r',"description": "string",'+ registry + r'"trigger":{"type": "'+replicationrule["trigger_type"]+r'", "trigger_settings":{"cron":"'+replicationrule["cron"]+r'"}},"filters":[ {"type":"name","value":"'+replicationrule["name_filters"]+r'"},{"type":"tag","value":"'+replicationrule["tag_filters"]+r'"}]}'))
print(body)
request(url+"replication/policies", 'post', **body)
else:
raise Exception(r"Error: Feature {} has no branch {}.".format(sys._getframe().f_code.co_name, branch))
@ -151,7 +151,7 @@ class HarborAPI:
}
}
body=dict(body=payload)
print body
print(body)
request(url+"projects/"+projectid+"", 'put', **body)
@get_feature_branch
@ -162,7 +162,7 @@ class HarborAPI:
cve_id_str = cve_id_str + '{"cve_id":"' +cve_id["id"] + '"}'
if index != len(cve_id_list["cve"]) - 1:
cve_id_str = cve_id_str + ","
body=dict(body=json.loads(r'{"items":['+cve_id_str.encode('utf-8')+r'],"expires_at":'+cve_id_list["expires_at"]+'}'))
body=dict(body=json.loads(r'{"items":['+cve_id_str+r'],"expires_at":'+cve_id_list["expires_at"]+'}'))
request(url+"system/CVEWhitelist", 'put', **body)
else:
raise Exception(r"Error: Feature {} has no branch {}.".format(sys._getframe().f_code.co_name, branch))
@ -177,12 +177,12 @@ class HarborAPI:
cve_id_str = cve_id_str + '{"cve_id":"' +cve_id["id"] + '"}'
if index != len(cve_id_list["cve"]) - 1:
cve_id_str = cve_id_str + ","
print cve_id_str
print(cve_id_str)
if reuse_sys_cve_whitelist == "true":
payload = r'{"metadata":{"reuse_sys_cve_whitelist":"true"}}'
else:
payload = r'{"metadata":{"reuse_sys_cve_whitelist":"false"},"cve_whitelist":{"project_id":'+projectid+',"items":['+cve_id_str.encode('utf-8')+r'],"expires_at":'+cve_id_list["expires_at"]+'}}'
print payload
payload = r'{"metadata":{"reuse_sys_cve_whitelist":"false"},"cve_whitelist":{"project_id":'+projectid+',"items":['+cve_id_str+r'],"expires_at":'+cve_id_list["expires_at"]+'}}'
print(payload)
body=dict(body=json.loads(payload))
request(url+"projects/"+projectid+"", 'put', **body)
else:
@ -191,7 +191,7 @@ class HarborAPI:
@get_feature_branch
def update_interrogation_services(self, cron, **kwargs):
payload = {"schedule":{"type":"Custom","cron": cron}}
print payload
print(payload)
body=dict(body=payload)
request(url+"system/scanAll/schedule", 'post', **body)
@ -217,7 +217,7 @@ class HarborAPI:
}
}
}
print payload
print(payload)
body=dict(body=payload)
request(url+"configurations", 'put', **body)
@ -256,7 +256,7 @@ class HarborAPI:
raise Exception(r"Error: Robot account count {} is not legal!".format(len(robot_account["access"])))
else:
raise Exception(r"Error: Feature {} has no branch {}.".format(sys._getframe().f_code.co_name, branch))
print payload
print(payload)
body=dict(body=payload)
request(url+"projects/"+projectid+"/robots", 'post', **body)
@ -306,7 +306,7 @@ class HarborAPI:
"ref":int(projectid)
}
}
print payload
print(payload)
body=dict(body=payload)
request(url+"retentions", 'post', **body)
else:
@ -343,7 +343,7 @@ class HarborAPI:
"priority":0,
"template":"immutable_template"
}
print payload
print(payload)
body=dict(body=payload)
request(url+"projects/"+projectid+"/immutabletagrules", 'post', **body)
else:
@ -375,7 +375,7 @@ class HarborAPI:
],
"enabled":webhook["enabled"]
}
print payload
print(payload)
body=dict(body=payload)
request(url+"projects/"+projectid+"/webhook/policies", 'post', **body)
else:
@ -383,7 +383,7 @@ class HarborAPI:
def update_repoinfo(self, reponame):
payload = {"description": "testdescription"}
print payload
print(payload)
body=dict(body=payload)
request(url+"repositories/"+reponame+"", 'put', **body)
@ -398,10 +398,10 @@ class HarborAPI:
if not os.path.exists(ca_path):
try:
os.makedirs(ca_path)
except Exception, e:
print str(e)
except Exception as e:
print(str(e))
pass
open(target, 'wb').write(ca_content)
open(target, 'wb').write(ca_content.encode('utf-8'))
def request(url, method, user = None, userp = None, **kwargs):
@ -415,7 +415,7 @@ def request(url, method, user = None, userp = None, **kwargs):
kwargs['headers']['Content-Type'] = 'application/json'
kwargs['data'] = json.dumps(kwargs['body'])
del kwargs['body']
print "url: ", url
print("url: ", url)
resp = requests.request(method, url, verify=False, auth=(user, userp), **kwargs)
if resp.status_code >= 400:
raise Exception("[Exception Message] - {}".format(resp.text))