mirror of https://github.com/goharbor/harbor.git
Compare commits
21 Commits
Author | SHA1 | Date |
---|---|---|
|
9384ed0e47 | |
|
af4843729c | |
|
647842f419 | |
|
b8ee76373f | |
|
9a932a0f9a | |
|
abc5e55ea9 | |
|
785b60bcbe | |
|
6d3bf31364 | |
|
4170738322 | |
|
028b393112 | |
|
c130e3d539 | |
|
a37118f518 | |
|
40e78d5545 | |
|
05d5b64ff9 | |
|
f019430872 | |
|
b7e00b2e53 | |
|
db1569ae20 | |
|
69c62ef41a | |
|
d569ba20d6 | |
|
f5f912a780 | |
|
15f3aabc0d |
|
@ -8,6 +8,18 @@
|
|||
* Add date here... Add signature here...
|
||||
- Add your reason here...
|
||||
|
||||
* May 20 2025 <yan-yw.wang@broadcom.com>
|
||||
- Refresh base image
|
||||
|
||||
* May 08 2025 <yan-yw.wang@broadcom.com>
|
||||
- Refresh base image
|
||||
|
||||
* Apr 08 2025 <yan-yw.wang@broadcom.com>
|
||||
- Refresh base image
|
||||
|
||||
* Apr 03 2025 <yan-yw.wang@broadcom.com>
|
||||
- Refresh base image
|
||||
|
||||
* Oct 24 2024 <yan-yw.wang@broadcom.com>
|
||||
- Refresh base image
|
||||
|
||||
|
@ -30,4 +42,4 @@
|
|||
- Refresh base image
|
||||
|
||||
* Jul 15 2021 <danfengl@vmware.com>
|
||||
- Create this file to trigger build base action in buld-package workflow
|
||||
- Create this file to trigger build base action in buld-package workflow
|
||||
|
|
|
@ -13,16 +13,14 @@ jobs:
|
|||
env:
|
||||
BUILD_PACKAGE: true
|
||||
runs-on:
|
||||
- ubuntu-20.04
|
||||
- ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: 'google-github-actions/auth@v2'
|
||||
- name: Configure AWS credentials
|
||||
uses: aws-actions/configure-aws-credentials@v4.1.0
|
||||
with:
|
||||
credentials_json: '${{ secrets.GCP_CREDENTIALS }}'
|
||||
- uses: google-github-actions/setup-gcloud@v2
|
||||
with:
|
||||
version: '430.0.0'
|
||||
- run: gcloud info
|
||||
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
aws-region: us-east-1
|
||||
- name: Set up Go 1.22
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
|
|
|
@ -17,14 +17,12 @@ jobs:
|
|||
#- self-hosted
|
||||
- ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- id: 'auth'
|
||||
name: 'Authenticate to Google Cloud'
|
||||
uses: google-github-actions/auth@v2
|
||||
- name: Configure AWS credentials
|
||||
uses: aws-actions/configure-aws-credentials@v4.1.0
|
||||
with:
|
||||
credentials_json: '${{ secrets.GCP_CREDENTIALS }}'
|
||||
- uses: google-github-actions/setup-gcloud@v2
|
||||
- run: gcloud info
|
||||
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
aws-region: us-east-1
|
||||
- name: Set up Go 1.21
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
|
@ -65,6 +63,5 @@ jobs:
|
|||
- name: upload test result to gs
|
||||
run: |
|
||||
cd src/github.com/goharbor/harbor
|
||||
gsutil cp ./distribution-spec/conformance/report.html gs://harbor-conformance-test/report.html
|
||||
gsutil acl ch -u AllUsers:R gs://harbor-conformance-test/report.html
|
||||
aws s3 cp ./distribution-spec/conformance/report.html s3://harbor-conformance-test/report.html
|
||||
if: always()
|
||||
|
|
|
@ -12,7 +12,7 @@ jobs:
|
|||
matrix:
|
||||
# maintain the versions of harbor that need to be actively
|
||||
# security scanned
|
||||
versions: [dev, v2.12.0-dev]
|
||||
versions: [dev, v2.13.0-dev]
|
||||
# list of images that need to be scanned
|
||||
images: [harbor-core, harbor-db, harbor-exporter, harbor-jobservice, harbor-log, harbor-portal, harbor-registryctl, prepare]
|
||||
permissions:
|
||||
|
|
|
@ -7,7 +7,7 @@ on:
|
|||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Setup env
|
||||
|
@ -19,12 +19,12 @@ jobs:
|
|||
echo "PRE_TAG=$(echo $release | jq -r '.body' | jq -r '.preTag')" >> $GITHUB_ENV
|
||||
echo "BRANCH=$(echo $release | jq -r '.target_commitish')" >> $GITHUB_ENV
|
||||
echo "PRERELEASE=$(echo $release | jq -r '.prerelease')" >> $GITHUB_ENV
|
||||
- uses: 'google-github-actions/auth@v2'
|
||||
- name: Configure AWS credentials
|
||||
uses: aws-actions/configure-aws-credentials@v4.1.0
|
||||
with:
|
||||
credentials_json: '${{ secrets.GCP_CREDENTIALS }}'
|
||||
- uses: google-github-actions/setup-gcloud@v2
|
||||
with:
|
||||
version: '430.0.0'
|
||||
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
aws-region: us-east-1
|
||||
- name: Prepare Assets
|
||||
run: |
|
||||
if [ ! ${{ env.BUILD_NO }} -o ${{ env.BUILD_NO }} = "null" ]
|
||||
|
@ -39,8 +39,8 @@ jobs:
|
|||
src_online_package=harbor-online-installer-${{ env.BASE_TAG }}-${{ env.BUILD_NO }}.tgz
|
||||
dst_offline_package=harbor-offline-installer-${{ env.CUR_TAG }}.tgz
|
||||
dst_online_package=harbor-online-installer-${{ env.CUR_TAG }}.tgz
|
||||
gsutil cp gs://${{ secrets.HARBOR_RELEASE_BUILD }}/${{ env.BRANCH }}/${src_offline_package} gs://${{ secrets.HARBOR_RELEASE_BUILD }}/${{ env.BRANCH }}/${dst_offline_package}
|
||||
gsutil cp gs://${{ secrets.HARBOR_RELEASE_BUILD }}/${{ env.BRANCH }}/${src_online_package} gs://${{ secrets.HARBOR_RELEASE_BUILD }}/${{ env.BRANCH }}/${dst_online_package}
|
||||
aws s3 cp s3://${{ secrets.HARBOR_RELEASE_BUILD }}/${{ env.BRANCH }}/${src_offline_package} s3://${{ secrets.HARBOR_RELEASE_BUILD }}/${{ env.BRANCH }}/${dst_offline_package}
|
||||
aws s3 cp s3://${{ secrets.HARBOR_RELEASE_BUILD }}/${{ env.BRANCH }}/${src_online_package} s3://${{ secrets.HARBOR_RELEASE_BUILD }}/${{ env.BRANCH }}/${dst_online_package}
|
||||
|
||||
assets_path=$(pwd)/assets
|
||||
source tools/release/release_utils.sh && getAssets ${{ secrets.HARBOR_RELEASE_BUILD }} ${{ env.BRANCH }} $dst_offline_package $dst_online_package ${{ env.PRERELEASE }} $assets_path
|
||||
|
|
10
Makefile
10
Makefile
|
@ -105,8 +105,8 @@ PREPARE_VERSION_NAME=versions
|
|||
|
||||
#versions
|
||||
REGISTRYVERSION=v2.8.3-patch-redis
|
||||
TRIVYVERSION=v0.61.0
|
||||
TRIVYADAPTERVERSION=v0.33.0-rc.2
|
||||
TRIVYVERSION=v0.62.1
|
||||
TRIVYADAPTERVERSION=v0.33.1
|
||||
NODEBUILDIMAGE=node:16.18.0
|
||||
|
||||
# version of registry for pulling the source code
|
||||
|
@ -308,7 +308,7 @@ define swagger_generate_server
|
|||
@$(SWAGGER_GENERATE_SERVER) -f $(1) -A $(3) --target $(2)
|
||||
endef
|
||||
|
||||
gen_apis: lint_apis
|
||||
gen_apis:
|
||||
$(call prepare_docker_image,${SWAGGER_IMAGENAME},${SWAGGER_VERSION},${SWAGGER_IMAGE_BUILD_CMD})
|
||||
$(call swagger_generate_server,api/v2.0/swagger.yaml,src/server/v2.0,harbor)
|
||||
|
||||
|
@ -338,7 +338,7 @@ versions_prepare:
|
|||
check_environment:
|
||||
@$(MAKEPATH)/$(CHECKENVCMD)
|
||||
|
||||
compile_core: gen_apis
|
||||
compile_core: lint_apis gen_apis
|
||||
@echo "compiling binary for core (golang image)..."
|
||||
@echo $(GOBUILDPATHINCONTAINER)
|
||||
@$(DOCKERCMD) run --rm -v $(BUILDPATH):$(GOBUILDPATHINCONTAINER) -w $(GOBUILDPATH_CORE) $(GOBUILDIMAGE) $(GOIMAGEBUILD_CORE) -o $(GOBUILDPATHINCONTAINER)/$(GOBUILDMAKEPATH_CORE)/$(CORE_BINARYNAME)
|
||||
|
@ -399,7 +399,7 @@ build:
|
|||
-e TRIVY_DOWNLOAD_URL=$(TRIVY_DOWNLOAD_URL) -e TRIVY_ADAPTER_DOWNLOAD_URL=$(TRIVY_ADAPTER_DOWNLOAD_URL) \
|
||||
-e PULL_BASE_FROM_DOCKERHUB=$(PULL_BASE_FROM_DOCKERHUB) -e BUILD_BASE=$(BUILD_BASE) \
|
||||
-e REGISTRYUSER=$(REGISTRYUSER) -e REGISTRYPASSWORD=$(REGISTRYPASSWORD) \
|
||||
-e PUSHBASEIMAGE=$(PUSHBASEIMAGE)
|
||||
-e PUSHBASEIMAGE=$(PUSHBASEIMAGE) -e GOBUILDIMAGE=$(GOBUILDIMAGE)
|
||||
|
||||
build_standalone_db_migrator: compile_standalone_db_migrator
|
||||
make -f $(MAKEFILEPATH_PHOTON)/Makefile _build_standalone_db_migrator -e BASEIMAGETAG=$(BASEIMAGETAG) -e VERSIONTAG=$(VERSIONTAG)
|
||||
|
|
|
@ -154,7 +154,7 @@ _build_trivy_adapter:
|
|||
$(call _extract_archive, $(TRIVY_ADAPTER_DOWNLOAD_URL), $(DOCKERFILEPATH_TRIVY_ADAPTER)/binary/) ; \
|
||||
else \
|
||||
echo "Building Trivy adapter $(TRIVYADAPTERVERSION) from sources..." ; \
|
||||
cd $(DOCKERFILEPATH_TRIVY_ADAPTER) && $(DOCKERFILEPATH_TRIVY_ADAPTER)/builder.sh $(TRIVYADAPTERVERSION) && cd - ; \
|
||||
cd $(DOCKERFILEPATH_TRIVY_ADAPTER) && $(DOCKERFILEPATH_TRIVY_ADAPTER)/builder.sh $(TRIVYADAPTERVERSION) $(GOBUILDIMAGE) && cd - ; \
|
||||
fi ; \
|
||||
echo "Building Trivy adapter container for photon..." ; \
|
||||
$(DOCKERBUILD_WITH_PULL_PARA) --build-arg harbor_base_image_version=$(BASEIMAGETAG) \
|
||||
|
@ -178,7 +178,7 @@ _build_registry:
|
|||
rm -rf $(DOCKERFILEPATH_REG)/binary && mkdir -p $(DOCKERFILEPATH_REG)/binary && \
|
||||
$(call _get_binary, $(REGISTRYURL), $(DOCKERFILEPATH_REG)/binary/registry); \
|
||||
else \
|
||||
cd $(DOCKERFILEPATH_REG) && $(DOCKERFILEPATH_REG)/builder $(REGISTRY_SRC_TAG) $(DISTRIBUTION_SRC) && cd - ; \
|
||||
cd $(DOCKERFILEPATH_REG) && $(DOCKERFILEPATH_REG)/builder $(REGISTRY_SRC_TAG) $(DISTRIBUTION_SRC) $(GOBUILDIMAGE) && cd - ; \
|
||||
fi
|
||||
@echo "building registry container for photon..."
|
||||
@chmod 655 $(DOCKERFILEPATH_REG)/binary/registry && $(DOCKERBUILD_WITH_PULL_PARA) --build-arg harbor_base_image_version=$(BASEIMAGETAG) --build-arg harbor_base_namespace=$(BASEIMAGENAMESPACE) -f $(DOCKERFILEPATH_REG)/$(DOCKERFILENAME_REG) -t $(DOCKERIMAGENAME_REG):$(VERSIONTAG) .
|
||||
|
|
|
@ -6,6 +6,8 @@ REGISTRY_CONTROLLER_URL={{registry_controller_url}}
|
|||
JOBSERVICE_WEBHOOK_JOB_MAX_RETRY={{notification_webhook_job_max_retry}}
|
||||
JOBSERVICE_WEBHOOK_JOB_HTTP_CLIENT_TIMEOUT={{notification_webhook_job_http_client_timeout}}
|
||||
|
||||
LOG_LEVEL={{log_level}}
|
||||
|
||||
{%if internal_tls.enabled %}
|
||||
INTERNAL_TLS_ENABLED=true
|
||||
INTERNAL_TLS_TRUST_CA_PATH=/harbor_cust_cert/harbor_internal_ca.crt
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
FROM golang:1.23.8
|
||||
ARG golang_image
|
||||
FROM ${golang_image}
|
||||
|
||||
ENV DISTRIBUTION_DIR /go/src/github.com/docker/distribution
|
||||
ENV BUILDTAGS include_oss include_gcs
|
||||
|
|
|
@ -14,6 +14,7 @@ fi
|
|||
|
||||
VERSION="$1"
|
||||
DISTRIBUTION_SRC="$2"
|
||||
GOBUILDIMAGE="$3"
|
||||
|
||||
set -e
|
||||
|
||||
|
@ -32,7 +33,7 @@ cd $cur
|
|||
|
||||
echo 'build the registry binary ...'
|
||||
cp Dockerfile.binary $TEMP
|
||||
docker build -f $TEMP/Dockerfile.binary -t registry-golang $TEMP
|
||||
docker build --build-arg golang_image=$GOBUILDIMAGE -f $TEMP/Dockerfile.binary -t registry-golang $TEMP
|
||||
|
||||
echo 'copy the registry binary to local...'
|
||||
ID=$(docker create registry-golang)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
FROM golang:1.23.8
|
||||
ARG golang_image
|
||||
FROM ${golang_image}
|
||||
|
||||
ADD . /go/src/github.com/goharbor/harbor-scanner-trivy/
|
||||
WORKDIR /go/src/github.com/goharbor/harbor-scanner-trivy/
|
||||
|
|
|
@ -8,6 +8,7 @@ if [ -z $1 ]; then
|
|||
fi
|
||||
|
||||
VERSION="$1"
|
||||
GOBUILDIMAGE="$2"
|
||||
|
||||
set -e
|
||||
|
||||
|
@ -19,9 +20,9 @@ TEMP=$(mktemp -d ${TMPDIR-/tmp}/trivy-adapter.XXXXXX)
|
|||
git clone https://github.com/goharbor/harbor-scanner-trivy.git $TEMP
|
||||
cd $TEMP; git checkout $VERSION; cd -
|
||||
|
||||
echo "Building Trivy adapter binary based on golang:1.23.8..."
|
||||
echo "Building Trivy adapter binary ..."
|
||||
cp Dockerfile.binary $TEMP
|
||||
docker build -f $TEMP/Dockerfile.binary -t trivy-adapter-golang $TEMP
|
||||
docker build --build-arg golang_image=$GOBUILDIMAGE -f $TEMP/Dockerfile.binary -t trivy-adapter-golang $TEMP
|
||||
|
||||
echo "Copying Trivy adapter binary from the container to the local directory..."
|
||||
ID=$(docker create trivy-adapter-golang)
|
||||
|
|
|
@ -28,6 +28,7 @@ import (
|
|||
"github.com/goharbor/harbor/src/controller/scan"
|
||||
"github.com/goharbor/harbor/src/core/service/token"
|
||||
"github.com/goharbor/harbor/src/jobservice/job"
|
||||
"github.com/goharbor/harbor/src/lib"
|
||||
"github.com/goharbor/harbor/src/lib/config"
|
||||
"github.com/goharbor/harbor/src/lib/errors"
|
||||
"github.com/goharbor/harbor/src/lib/log"
|
||||
|
@ -341,13 +342,18 @@ func (de *defaultEnforcer) PreheatArtifact(ctx context.Context, art *artifact.Ar
|
|||
|
||||
// getCandidates get the initial candidates by evaluating the policy
|
||||
func (de *defaultEnforcer) getCandidates(ctx context.Context, ps *pol.Schema, p *proModels.Project) ([]*selector.Candidate, error) {
|
||||
// Filter the candidates by supported types.
|
||||
var supportedTypes []any
|
||||
for _, t := range lib.SliceToUpper(pr.SupportedTypes) {
|
||||
supportedTypes = append(supportedTypes, t)
|
||||
}
|
||||
// Get the initial candidates
|
||||
// Here we have a hidden filter, the artifact type filter.
|
||||
// Only get the image type at this moment.
|
||||
arts, err := de.artCtl.List(ctx, &q.Query{
|
||||
Keywords: map[string]interface{}{
|
||||
"ProjectID": ps.ProjectID,
|
||||
"Type": strings.ToUpper(pr.SupportedType),
|
||||
"Type": q.NewOrList(supportedTypes),
|
||||
},
|
||||
}, &artifact.Option{
|
||||
WithLabel: true,
|
||||
|
@ -433,7 +439,7 @@ func (de *defaultEnforcer) startTask(ctx context.Context, executionID int64, can
|
|||
}
|
||||
|
||||
pi := &pr.PreheatImage{
|
||||
Type: pr.SupportedType,
|
||||
Type: candidate.Kind,
|
||||
URL: u,
|
||||
Headers: map[string]interface{}{
|
||||
accessCredHeaderKey: cred,
|
||||
|
@ -517,7 +523,7 @@ func (de *defaultEnforcer) toCandidates(ctx context.Context, p *proModels.Projec
|
|||
NamespaceID: p.ProjectID,
|
||||
Namespace: p.Name,
|
||||
Repository: pureRepository(p.Name, a.RepositoryName),
|
||||
Kind: pr.SupportedType,
|
||||
Kind: strings.ToLower(a.Type),
|
||||
Digest: a.Digest,
|
||||
Tags: []string{t.Name},
|
||||
Labels: getLabels(a.Labels),
|
||||
|
|
|
@ -67,14 +67,14 @@ require (
|
|||
go.pinniped.dev v0.37.0
|
||||
go.uber.org/ratelimit v0.3.1
|
||||
golang.org/x/crypto v0.36.0
|
||||
golang.org/x/net v0.37.0
|
||||
golang.org/x/net v0.38.0
|
||||
golang.org/x/oauth2 v0.27.0
|
||||
golang.org/x/sync v0.12.0
|
||||
golang.org/x/text v0.23.0
|
||||
golang.org/x/time v0.11.0
|
||||
gopkg.in/h2non/gock.v1 v1.1.2
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
helm.sh/helm/v3 v3.17.2
|
||||
helm.sh/helm/v3 v3.17.3
|
||||
k8s.io/api v0.32.2
|
||||
k8s.io/apimachinery v0.32.2
|
||||
k8s.io/client-go v0.32.2
|
||||
|
|
|
@ -693,8 +693,8 @@ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
|||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
|
||||
golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
|
||||
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
||||
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
|
||||
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M=
|
||||
golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
|
||||
|
@ -874,8 +874,8 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
|||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=
|
||||
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
|
||||
helm.sh/helm/v3 v3.17.2 h1:agYQ5ew2jq5vdx2K7q5W44KyKQrnSubUMCQsjkiv3/o=
|
||||
helm.sh/helm/v3 v3.17.2/go.mod h1:+uJKMH/UiMzZQOALR3XUf3BLIoczI2RKKD6bMhPh4G8=
|
||||
helm.sh/helm/v3 v3.17.3 h1:3n5rW3D0ArjFl0p4/oWO8IbY/HKaNNwJtOQFdH2AZHg=
|
||||
helm.sh/helm/v3 v3.17.3/go.mod h1:+uJKMH/UiMzZQOALR3XUf3BLIoczI2RKKD6bMhPh4G8=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
|
|
|
@ -22,6 +22,7 @@ import (
|
|||
|
||||
"github.com/beego/beego/v2/client/orm"
|
||||
|
||||
"github.com/goharbor/harbor/src/lib/log"
|
||||
"github.com/goharbor/harbor/src/lib/q"
|
||||
)
|
||||
|
||||
|
@ -155,7 +156,12 @@ func setFilters(ctx context.Context, qs orm.QuerySeter, query *q.Query, meta *me
|
|||
// The "strings.SplitN()" here is a workaround for the incorrect usage of query which should be avoided
|
||||
// e.g. use the query with the knowledge of underlying ORM implementation, the "OrList" should be used instead:
|
||||
// https://github.com/goharbor/harbor/blob/v2.2.0/src/controller/project/controller.go#L348
|
||||
k := strings.SplitN(key, orm.ExprSep, 2)[0]
|
||||
keyPieces := strings.Split(key, orm.ExprSep)
|
||||
if len(keyPieces) > 2 {
|
||||
log.Warningf("The separator '%s' is not valid in the query parameter '%s__%s'. Please use the correct field name.", orm.ExprSep, keyPieces[0], keyPieces[1])
|
||||
continue
|
||||
}
|
||||
k := keyPieces[0]
|
||||
mk, filterable := meta.Filterable(k)
|
||||
if !filterable {
|
||||
// This is a workaround for the unsuitable usage of query, the keyword format for field and method should be consistent
|
||||
|
|
|
@ -33,3 +33,13 @@ func Title(s string) string {
|
|||
title := cases.Title(language.Und)
|
||||
return title.String(strings.ToLower(s))
|
||||
}
|
||||
|
||||
// SliceToUpper converts a slice of strings to uppercase.
|
||||
func SliceToUpper(s []string) []string {
|
||||
result := make([]string, len(s))
|
||||
for i, str := range s {
|
||||
result[i] = strings.ToUpper(str)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
package lib
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
@ -52,3 +53,56 @@ func TestTitle(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSliceToUpper(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input []string
|
||||
expected []string
|
||||
}{
|
||||
{
|
||||
name: "Empty slice",
|
||||
input: []string{},
|
||||
expected: []string{},
|
||||
},
|
||||
{
|
||||
name: "Single element",
|
||||
input: []string{"hello"},
|
||||
expected: []string{"HELLO"},
|
||||
},
|
||||
{
|
||||
name: "Multiple elements",
|
||||
input: []string{"hello", "world", "go"},
|
||||
expected: []string{"HELLO", "WORLD", "GO"},
|
||||
},
|
||||
{
|
||||
name: "Already uppercase",
|
||||
input: []string{"HELLO", "WORLD"},
|
||||
expected: []string{"HELLO", "WORLD"},
|
||||
},
|
||||
{
|
||||
name: "Mixed case",
|
||||
input: []string{"Hello", "World", "Go"},
|
||||
expected: []string{"HELLO", "WORLD", "GO"},
|
||||
},
|
||||
{
|
||||
name: "With special characters",
|
||||
input: []string{"hello!", "world?", "go#"},
|
||||
expected: []string{"HELLO!", "WORLD?", "GO#"},
|
||||
},
|
||||
{
|
||||
name: "With numbers",
|
||||
input: []string{"hello123", "world456"},
|
||||
expected: []string{"HELLO123", "WORLD456"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result := SliceToUpper(tt.input)
|
||||
if !reflect.DeepEqual(result, tt.expected) {
|
||||
t.Errorf("SliceToUpper() = %v, want %v", result, tt.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,17 @@ const (
|
|||
|
||||
// dragonflyJobPath is the job path for dragonfly openapi.
|
||||
dragonflyJobPath = "/oapi/v1/jobs"
|
||||
)
|
||||
|
||||
const (
|
||||
// preheatTypeImage represents the image to the dragonfly cluster.
|
||||
preheatTypeImage = "image"
|
||||
|
||||
// preheatTypeFile represents the file to the dragonfly cluster.
|
||||
preheatTypeFile = "file"
|
||||
)
|
||||
|
||||
const (
|
||||
// scopeTypeSingleSeedPeer represents preheat image to single seed peer in p2p cluster.
|
||||
scopeTypeSingleSeedPeer = "single_seed_peer"
|
||||
|
||||
|
@ -233,9 +243,9 @@ func (dd *DragonflyDriver) Preheat(preheatingImage *PreheatImage) (*PreheatingSt
|
|||
// Construct the preheat job request by the given parameters of the preheating image .
|
||||
req := &dragonflyCreateJobRequest{
|
||||
Type: "preheat",
|
||||
// TODO: Support set SchedulerClusterIDs, FilteredQueryParam, ConcurrentCount and Timeout.
|
||||
// TODO: Support set FilteredQueryParam, ConcurrentCount and Timeout.
|
||||
Args: dragonflyCreateJobRequestArgs{
|
||||
Type: preheatingImage.Type,
|
||||
Type: preheatTypeImage,
|
||||
URL: preheatingImage.URL,
|
||||
Headers: headerToMapString(preheatingImage.Headers),
|
||||
},
|
||||
|
|
|
@ -17,13 +17,17 @@ package provider
|
|||
import (
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"slices"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
// SupportedType indicates the supported preheating type 'image'.
|
||||
SupportedType = "image"
|
||||
var (
|
||||
// SupportedTypes indicates the supported preheating types.
|
||||
SupportedTypes = []string{
|
||||
"image",
|
||||
"cnai",
|
||||
}
|
||||
)
|
||||
|
||||
// PreheatImage contains related information which can help providers to get/pull the images.
|
||||
|
@ -75,7 +79,7 @@ func (img *PreheatImage) ToJSON() (string, error) {
|
|||
|
||||
// Validate PreheatImage
|
||||
func (img *PreheatImage) Validate() error {
|
||||
if img.Type != SupportedType {
|
||||
if !slices.Contains(SupportedTypes, img.Type) {
|
||||
return errors.Errorf("unsupported type '%s'", img.Type)
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -9,7 +9,7 @@
|
|||
"dependencies": {
|
||||
"css-loader": "^6.11.0",
|
||||
"style-loader": "^3.3.4",
|
||||
"swagger-ui": "5.17.14"
|
||||
"swagger-ui": "5.20.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"clean-webpack-plugin": "^4.0.0",
|
||||
|
|
|
@ -786,11 +786,12 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/@babel/code-frame": {
|
||||
"version": "7.24.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz",
|
||||
"integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==",
|
||||
"version": "7.26.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz",
|
||||
"integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==",
|
||||
"dependencies": {
|
||||
"@babel/highlight": "^7.24.7",
|
||||
"@babel/helper-validator-identifier": "^7.25.9",
|
||||
"js-tokens": "^4.0.0",
|
||||
"picocolors": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
|
@ -1159,17 +1160,17 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@babel/helper-string-parser": {
|
||||
"version": "7.24.8",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz",
|
||||
"integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==",
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz",
|
||||
"integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==",
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-validator-identifier": {
|
||||
"version": "7.24.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz",
|
||||
"integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==",
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz",
|
||||
"integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
|
@ -1211,50 +1212,36 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@babel/helpers": {
|
||||
"version": "7.25.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.6.tgz",
|
||||
"integrity": "sha512-Xg0tn4HcfTijTwfDwYlvVCl43V6h4KyVVX2aEm4qdO/PC6L2YvzLHFdmxhoeSA3eslcE6+ZVXHgWwopXYLNq4Q==",
|
||||
"version": "7.26.10",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.10.tgz",
|
||||
"integrity": "sha512-UPYc3SauzZ3JGgj87GgZ89JVdC5dj0AoetR5Bw6wj4niittNyFh6+eOGonYvJ1ao6B8lEa3Q3klS7ADZ53bc5g==",
|
||||
"dependencies": {
|
||||
"@babel/template": "^7.25.0",
|
||||
"@babel/types": "^7.25.6"
|
||||
"@babel/template": "^7.26.9",
|
||||
"@babel/types": "^7.26.10"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helpers/node_modules/@babel/template": {
|
||||
"version": "7.25.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz",
|
||||
"integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==",
|
||||
"version": "7.26.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.9.tgz",
|
||||
"integrity": "sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==",
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.24.7",
|
||||
"@babel/parser": "^7.25.0",
|
||||
"@babel/types": "^7.25.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/highlight": {
|
||||
"version": "7.24.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz",
|
||||
"integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==",
|
||||
"dependencies": {
|
||||
"@babel/helper-validator-identifier": "^7.24.7",
|
||||
"chalk": "^2.4.2",
|
||||
"js-tokens": "^4.0.0",
|
||||
"picocolors": "^1.0.0"
|
||||
"@babel/code-frame": "^7.26.2",
|
||||
"@babel/parser": "^7.26.9",
|
||||
"@babel/types": "^7.26.9"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/parser": {
|
||||
"version": "7.25.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz",
|
||||
"integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==",
|
||||
"version": "7.26.10",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.10.tgz",
|
||||
"integrity": "sha512-6aQR2zGE/QFi8JpDLjUZEPYOs7+mhKXm86VaKFiLP35JQwQb6bwUE+XbvkH0EptsYhbNBSUGaUBLKqxH1xSgsA==",
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.25.6"
|
||||
"@babel/types": "^7.26.10"
|
||||
},
|
||||
"bin": {
|
||||
"parser": "bin/babel-parser.js"
|
||||
|
@ -2609,13 +2596,12 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@babel/types": {
|
||||
"version": "7.25.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz",
|
||||
"integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==",
|
||||
"version": "7.26.10",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.10.tgz",
|
||||
"integrity": "sha512-emqcG3vHrpxUKTrxcblR36dcrcoRDvKmnL/dCL6ZsHaShW80qxCAcNhzQZrpeM765VzEos+xOi4s+r4IXzTwdQ==",
|
||||
"dependencies": {
|
||||
"@babel/helper-string-parser": "^7.24.8",
|
||||
"@babel/helper-validator-identifier": "^7.24.7",
|
||||
"to-fast-properties": "^2.0.0"
|
||||
"@babel/helper-string-parser": "^7.25.9",
|
||||
"@babel/helper-validator-identifier": "^7.25.9"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
|
@ -5276,6 +5262,7 @@
|
|||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"color-convert": "^1.9.0"
|
||||
},
|
||||
|
@ -5501,9 +5488,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.7.7",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz",
|
||||
"integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==",
|
||||
"version": "1.8.4",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.8.4.tgz",
|
||||
"integrity": "sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.15.6",
|
||||
|
@ -6078,19 +6065,6 @@
|
|||
"integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/chalk": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^3.2.1",
|
||||
"escape-string-regexp": "^1.0.5",
|
||||
"supports-color": "^5.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/chardet": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
|
||||
|
@ -6299,6 +6273,7 @@
|
|||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"color-name": "1.1.3"
|
||||
}
|
||||
|
@ -6306,7 +6281,8 @@
|
|||
"node_modules/color-name": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
|
||||
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/color-support": {
|
||||
"version": "1.1.3",
|
||||
|
@ -8443,6 +8419,7 @@
|
|||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
}
|
||||
|
@ -9898,14 +9875,6 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/has-flag": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/has-property-descriptors": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
|
||||
|
@ -17128,17 +17097,6 @@
|
|||
"integrity": "sha512-osIBl6BGUmSfDkyH2mB7EFvCJntXDrLhKjHTRj/rK6xLH0yuPrHULDRQzKokSOD4VoorhtKpfcfW1GAntu8now==",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/supports-color": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
||||
"dependencies": {
|
||||
"has-flag": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/supports-hyperlinks": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz",
|
||||
|
@ -17546,14 +17504,6 @@
|
|||
"node": ">=8.17.0"
|
||||
}
|
||||
},
|
||||
"node_modules/to-fast-properties": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
|
||||
"integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/to-regex-range": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
*ngIf="isImage(artifact)"
|
||||
[title]="getPullCommandForRuntimeByDigest(artifact)"
|
||||
[iconMode]="true"
|
||||
id="pullCommandForDigest"
|
||||
(onCopySuccess)="
|
||||
onCpSuccess(getPullCommandForRuntimeByDigest(artifact))
|
||||
"
|
||||
|
@ -12,6 +13,7 @@
|
|||
<div
|
||||
*ngIf="isCNAB(artifact)"
|
||||
class="flex"
|
||||
id="pullCommandForCNAB"
|
||||
aria-label="Dropdown header Action">
|
||||
<hbr-copy-input
|
||||
[title]="getPullCommandForCNAB(artifact)"
|
||||
|
@ -20,8 +22,9 @@
|
|||
[defaultValue]="getPullCommandForCNAB(artifact)"></hbr-copy-input>
|
||||
</div>
|
||||
<div
|
||||
*ngIf="isChart(artifact)"
|
||||
*ngIf="isChart(artifact) && artifact.tagNumber > 0"
|
||||
class="flex"
|
||||
id="pullCommandForChart"
|
||||
aria-label="Dropdown header Action">
|
||||
<hbr-copy-input
|
||||
[title]="getPullCommandForChart(artifact)"
|
||||
|
|
|
@ -14,7 +14,8 @@
|
|||
import { PullCommandComponent } from './pull-command.component';
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { SharedTestingModule } from '../../../../../../../../shared/shared.module';
|
||||
import { ArtifactType } from '../../../../artifact'; // Import the necessary type
|
||||
import { ArtifactType, Clients } from '../../../../artifact'; // Import the necessary type
|
||||
import { ArtifactFront } from '../../../../artifact';
|
||||
|
||||
describe('PullCommandComponent', () => {
|
||||
let component: PullCommandComponent;
|
||||
|
@ -29,11 +30,11 @@ describe('PullCommandComponent', () => {
|
|||
fixture = TestBed.createComponent(PullCommandComponent);
|
||||
component = fixture.componentInstance;
|
||||
|
||||
// Mock the artifact input with a valid value
|
||||
component.artifact = {
|
||||
type: ArtifactType.IMAGE,
|
||||
digest: 'sampleDigest',
|
||||
tags: [{ name: 'latest' }],
|
||||
type: ArtifactType.CHART,
|
||||
tagNumber: 1,
|
||||
digest: 'sha256@digest',
|
||||
tags: [{ name: '1.0.0' }],
|
||||
};
|
||||
|
||||
fixture.detectChanges();
|
||||
|
@ -42,4 +43,69 @@ describe('PullCommandComponent', () => {
|
|||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should not display pull command for chart', async () => {
|
||||
// Mock the artifact input with a valid value
|
||||
component.artifact = {
|
||||
type: ArtifactType.CHART,
|
||||
tagNumber: 0,
|
||||
digest: 'sha256@digest',
|
||||
tags: [],
|
||||
};
|
||||
component.getPullCommandForChart(component.artifact);
|
||||
expect(
|
||||
component.getPullCommandForChart(component.artifact).length
|
||||
).toBe(0);
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
const modal =
|
||||
fixture.nativeElement.querySelector(`#pullCommandForChart`);
|
||||
expect(modal).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should display when pull command for chart is available', async () => {
|
||||
// Mock the artifact input with a valid value
|
||||
component.artifact = {
|
||||
type: ArtifactType.CHART,
|
||||
tagNumber: 1,
|
||||
digest: 'sha256@digest',
|
||||
tags: [{ name: '1.0.0' }],
|
||||
};
|
||||
component.getPullCommandForChart(component.artifact);
|
||||
expect(
|
||||
component.getPullCommandForChart(component.artifact).length
|
||||
).toBeGreaterThan(0);
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
const modal =
|
||||
fixture.nativeElement.querySelector(`#pullCommandForChart`);
|
||||
expect(modal).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should display when pull command for digest is available', async () => {
|
||||
// Mock the artifact input with a valid value
|
||||
component.artifact = {
|
||||
type: ArtifactType.IMAGE,
|
||||
};
|
||||
component.getPullCommandForRuntimeByDigest(component.artifact);
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
const modal = fixture.nativeElement.querySelector(
|
||||
`#pullCommandForDigest`
|
||||
);
|
||||
expect(modal).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should display when pull command for CNAB is available', async () => {
|
||||
// Mock the artifact input with a valid value
|
||||
component.artifact = {
|
||||
type: ArtifactType.CNAB,
|
||||
};
|
||||
component.getPullCommandForCNAB(component.artifact);
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
const modal =
|
||||
fixture.nativeElement.querySelector(`#pullCommandForCNAB`);
|
||||
expect(modal).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -100,14 +100,18 @@ export class PullCommandComponent {
|
|||
}
|
||||
|
||||
getPullCommandForChart(artifact: Artifact): string {
|
||||
return getPullCommandByTag(
|
||||
artifact.type,
|
||||
`${this.registryUrl ? this.registryUrl : location.hostname}/${
|
||||
this.projectName
|
||||
}/${this.repoName}`,
|
||||
artifact.tags[0].name,
|
||||
Clients.CHART
|
||||
);
|
||||
if (artifact.tagNumber > 0) {
|
||||
return getPullCommandByTag(
|
||||
artifact.type,
|
||||
`${this.registryUrl ? this.registryUrl : location.hostname}/${
|
||||
this.projectName
|
||||
}/${this.repoName}`,
|
||||
artifact.tags[0].name,
|
||||
Clients.CHART
|
||||
);
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
// For tagMode
|
||||
|
|
|
@ -17,6 +17,7 @@ package handler
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"html/template"
|
||||
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
|
||||
|
@ -235,7 +236,7 @@ func (r *repositoryAPI) UpdateRepository(ctx context.Context, params operation.U
|
|||
if err := r.repoCtl.Update(ctx, &repomodel.RepoRecord{
|
||||
RepositoryID: repository.RepositoryID,
|
||||
Name: repository.Name,
|
||||
Description: params.Repository.Description,
|
||||
Description: template.HTMLEscapeString(params.Repository.Description),
|
||||
}, "Description"); err != nil {
|
||||
return r.SendError(ctx, err)
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ set -x
|
|||
|
||||
#source gskey.sh
|
||||
|
||||
sudo gsutil version -l
|
||||
sudo aws --version
|
||||
|
||||
harbor_logs_bucket="harbor-ci-logs"
|
||||
|
||||
|
@ -12,8 +12,7 @@ E2E_IMAGE="goharbor/harbor-e2e-engine:latest-api"
|
|||
|
||||
# GS util
|
||||
function uploader {
|
||||
sudo gsutil cp $1 gs://$2/$1
|
||||
sudo gsutil acl ch -u AllUsers:R gs://$2/$1
|
||||
sudo aws s3 cp $1 s3://$2/$1
|
||||
}
|
||||
|
||||
set +e
|
||||
|
@ -38,18 +37,18 @@ else
|
|||
fi
|
||||
rc=$?
|
||||
## --------------------------------------------- Upload Harbor CI Logs -------------------------------------------
|
||||
timestamp=$(date +%s)
|
||||
GIT_COMMIT=$(git rev-parse --short "$GITHUB_SHA")
|
||||
outfile="integration_logs_$timestamp$GIT_COMMIT.tar.gz"
|
||||
sudo tar -zcvf $outfile output.xml log.html /var/log/harbor/*
|
||||
if [ -f "$outfile" ]; then
|
||||
uploader $outfile $harbor_logs_bucket
|
||||
echo "----------------------------------------------"
|
||||
echo "Download test logs:"
|
||||
echo "https://storage.googleapis.com/harbor-ci-logs/$outfile"
|
||||
echo "----------------------------------------------"
|
||||
else
|
||||
echo "No log output file to upload"
|
||||
fi
|
||||
#timestamp=$(date +%s)
|
||||
#GIT_COMMIT=$(git rev-parse --short "$GITHUB_SHA")
|
||||
#outfile="integration_logs_$timestamp$GIT_COMMIT.tar.gz"
|
||||
#sudo tar -zcvf $outfile output.xml log.html /var/log/harbor/*
|
||||
#if [ -f "$outfile" ]; then
|
||||
# uploader $outfile $harbor_logs_bucket
|
||||
# echo "----------------------------------------------"
|
||||
# echo "Download test logs:"
|
||||
# echo "https://storage.googleapis.com/harbor-ci-logs/$outfile"
|
||||
# echo "----------------------------------------------"
|
||||
#else
|
||||
# echo "No log output file to upload"
|
||||
#fi
|
||||
|
||||
exit $rc
|
||||
|
|
|
@ -4,8 +4,7 @@ set -x
|
|||
set -e
|
||||
|
||||
function uploader {
|
||||
gsutil cp $1 gs://$2/$1
|
||||
gsutil -D setacl public-read gs://$2/$1 &> /dev/null
|
||||
aws s3 cp $1 s3://$2/$1
|
||||
}
|
||||
|
||||
function publishImage {
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
# limitations under the License.
|
||||
#
|
||||
set -x
|
||||
gsutil version -l
|
||||
aws --version
|
||||
set +x
|
||||
|
||||
docker-compose version
|
||||
|
@ -58,17 +58,6 @@ else
|
|||
harbor_target_bucket=$harbor_releases_bucket/$DRONE_BRANCH
|
||||
fi
|
||||
|
||||
# GC credentials
|
||||
keyfile="/root/harbor-ci-logs.key"
|
||||
botofile="/root/.boto"
|
||||
echo -n $GS_PRIVATE_KEY > $keyfile
|
||||
chmod 400 $keyfile
|
||||
echo "[Credentials]" >> $botofile
|
||||
echo "gs_service_key_file = $keyfile" >> $botofile
|
||||
echo "gs_service_client_id = $GS_CLIENT_EMAIL" >> $botofile
|
||||
echo "[GSUtil]" >> $botofile
|
||||
echo "content_language = en" >> $botofile
|
||||
echo "default_project_id = $GS_PROJECT_ID" >> $botofile
|
||||
container_ip=`ip addr s eth0 |grep "inet "|awk '{print $2}' |awk -F "/" '{print $1}'`
|
||||
echo $container_ip
|
||||
|
||||
|
@ -106,10 +95,9 @@ echo "Harbor Assets version: $Harbor_Assets_Version"
|
|||
echo "Harbor Build Base tag: $Harbor_Build_Base_Tag"
|
||||
echo "--------------------------------------------------"
|
||||
|
||||
# GS util
|
||||
# AWS S3 util
|
||||
function uploader {
|
||||
gsutil cp $1 gs://$2/$1
|
||||
gsutil -D setacl public-read gs://$2/$1 &> /dev/null
|
||||
aws s3 cp $1 s3://$2/$1
|
||||
}
|
||||
|
||||
function package_installer {
|
||||
|
|
|
@ -74,19 +74,19 @@ Check The Search By One Condition
|
|||
Select From List By Value ${vulnerabilities_filter_select} project_id
|
||||
Retry Text Input ${vulnerabilities_filter_input} ${project_name}
|
||||
Retry Button Click ${security_hub_search_btn}
|
||||
Retry Wait Element Count //div[@class='datagrid']//clr-dg-cell[2][starts-with(@title, '${project_name}')] 10
|
||||
Retry Wait Element Count //div[@class='datagrid']//clr-dg-cell[2][starts-with(@title, '${project_name}')] 15
|
||||
# Check the search by repository name
|
||||
Select From List By Value ${vulnerabilities_filter_select} repository_name
|
||||
Retry Text Input ${vulnerabilities_filter_input} ${repository_name}
|
||||
Retry Button Click ${security_hub_search_btn}
|
||||
Retry Wait Element Count //div[@class='datagrid']//clr-dg-cell[2][@title='${repository_name}'] 10
|
||||
Retry Wait Element Count //div[@class='datagrid']//clr-dg-cell[2][@title='${repository_name}'] 15
|
||||
# Check the search by artifact digest
|
||||
Select From List By Value ${vulnerabilities_filter_select} digest
|
||||
Retry Text Input ${vulnerabilities_filter_input} ${digest}
|
||||
Retry Button Click ${security_hub_search_btn}
|
||||
Retry Wait Element Count //div[@class='datagrid']//clr-dg-cell[3][@title='${digest}'] 10
|
||||
Retry Wait Element Count //div[@class='datagrid']//clr-dg-cell[3][@title='${digest}'] 15
|
||||
${short_digest}= Set Variable ${digest}[0:15]
|
||||
Retry Wait Element Count //div[@class='datagrid']//clr-dg-cell[3]//a[text()='${short_digest}'] 10
|
||||
Retry Wait Element Count //div[@class='datagrid']//clr-dg-cell[3]//a[text()='${short_digest}'] 15
|
||||
# Check the search by CVE ID
|
||||
Select From List By Value ${vulnerabilities_filter_select} cve_id
|
||||
Retry Text Input ${vulnerabilities_filter_input} ${cve_id}
|
||||
|
@ -96,12 +96,12 @@ Check The Search By One Condition
|
|||
Select From List By Value ${vulnerabilities_filter_select} package
|
||||
Retry Text Input ${vulnerabilities_filter_input} ${package}
|
||||
Retry Button Click ${security_hub_search_btn}
|
||||
Retry Wait Element Count //div[@class='datagrid']//clr-dg-cell[7][@title='${package}'] 10
|
||||
Retry Wait Element Count //div[@class='datagrid']//clr-dg-cell[7][@title='${package}'] 15
|
||||
# Check the search by tag
|
||||
Select From List By Value ${vulnerabilities_filter_select} tag
|
||||
Retry Text Input ${vulnerabilities_filter_input} ${tag}
|
||||
Retry Button Click ${security_hub_search_btn}
|
||||
Retry Wait Element Count //div[@class='datagrid']//clr-dg-cell[4][text()='${tag}'] 10
|
||||
Retry Wait Element Count //div[@class='datagrid']//clr-dg-cell[4][text()='${tag}'] 15
|
||||
# Check the search by CVSS3
|
||||
Select From List By Value ${vulnerabilities_filter_select} cvss_score_v3
|
||||
${cvss3_from_input}= Format String {}{} ${vulnerabilities_filter_input} [1]
|
||||
|
@ -109,28 +109,28 @@ Check The Search By One Condition
|
|||
Retry Text Input ${cvss3_from_input} ${cvss_score_v3_from}
|
||||
Retry Text Input ${cvss3_to_input} ${cvss_score_v3_to}
|
||||
Retry Button Click ${security_hub_search_btn}
|
||||
Retry Wait Element Count //div[@class='datagrid']//clr-dg-cell[5][text()>=${cvss_score_v3_from} and text()<=${cvss_score_v3_to}] 10
|
||||
Retry Wait Element Count //div[@class='datagrid']//clr-dg-cell[5][text()>=${cvss_score_v3_from} and text()<=${cvss_score_v3_to}] 15
|
||||
# Check the search by severity
|
||||
# Critical
|
||||
Select From List By Value ${vulnerabilities_filter_select} severity
|
||||
Select From List By Value //form//div[2]//select Critical
|
||||
Retry Button Click ${security_hub_search_btn}
|
||||
Retry Wait Element Count //div[@class='datagrid']//clr-dg-cell[6]//span[text()='Critical'] 10
|
||||
Retry Wait Element Count //div[@class='datagrid']//clr-dg-cell[6]//span[text()='Critical'] 15
|
||||
Retry Wait Element //clr-dg-footer//span[text()='${summary["critical_cnt"]} CVEs']
|
||||
# High
|
||||
Select From List By Value //form//div[2]//select High
|
||||
Retry Button Click ${security_hub_search_btn}
|
||||
Retry Wait Element Count //div[@class='datagrid']//clr-dg-cell[6]//span[text()='High'] 10
|
||||
Retry Wait Element Count //div[@class='datagrid']//clr-dg-cell[6]//span[text()='High'] 15
|
||||
Retry Wait Element //clr-dg-footer//span[text()='${summary["high_cnt"]} CVEs']
|
||||
# Medium
|
||||
Select From List By Value //form//div[2]//select Medium
|
||||
Retry Button Click ${security_hub_search_btn}
|
||||
Retry Wait Element Count //div[@class='datagrid']//clr-dg-cell[6]//span[text()='Medium'] 10
|
||||
Retry Wait Element Count //div[@class='datagrid']//clr-dg-cell[6]//span[text()='Medium'] 15
|
||||
Retry Wait Element //clr-dg-footer//span[text()='${summary["medium_cnt"]} CVEs']
|
||||
# Low
|
||||
Select From List By Value //form//div[2]//select Low
|
||||
Retry Button Click ${security_hub_search_btn}
|
||||
Retry Wait Element Count //div[@class='datagrid']//clr-dg-cell[6]//span[text()='Low'] 10
|
||||
Retry Wait Element Count //div[@class='datagrid']//clr-dg-cell[6]//span[text()='Low'] 15
|
||||
Retry Wait Element //clr-dg-footer//span[text()='${summary["low_cnt"]} CVEs']
|
||||
# n/a
|
||||
Select From List By Value //form//div[2]//select Unknown
|
||||
|
|
|
@ -86,7 +86,7 @@ Test Case - Security Hub
|
|||
# Check the vulnerabilities search
|
||||
Retry Wait Element Not Visible ${add_search_criteria_icon}
|
||||
Retry Wait Element Not Visible ${remove_search_criteria_icon}
|
||||
Retry Wait Element Count ${vulnerabilities_datagrid_row} 10
|
||||
Retry Wait Element Count ${vulnerabilities_datagrid_row} 15
|
||||
Check The Quick Search
|
||||
Check The Search By One Condition project${d} project${d}/${images}[2] ${digest} ${cve_id} ${package} ${tag} ${cvss_score_v3_from} ${cvss_score_v3_to} ${summary}
|
||||
Check The Search By All Condition project${d} project${d}/${images}[2] ${digest} ${cve_id} ${package} ${tag} ${cvss_score_v3_from} ${cvss_score_v3_to} ${severity}
|
||||
|
|
|
@ -9,12 +9,12 @@ function getAssets {
|
|||
local prerelease=$5
|
||||
local assetsPath=$6
|
||||
mkdir $assetsPath && pushd $assetsPath
|
||||
gsutil cp gs://$bucket/$branch/$offlinePackage .
|
||||
aws s3 cp s3://$bucket/$branch/$offlinePackage .
|
||||
md5sum $offlinePackage > md5sum
|
||||
# Pre-release does not handle online installer packages
|
||||
if [ $prerelease = "false" ]
|
||||
then
|
||||
gsutil cp gs://$bucket/$branch/$onlinePackage .
|
||||
aws s3 cp s3://$bucket/$branch/$onlinePackage .
|
||||
md5sum $onlinePackage >> md5sum
|
||||
fi
|
||||
popd
|
||||
|
|
Loading…
Reference in New Issue