From d13a50e2ee26e4cf0589f484e0303f1d594b361c Mon Sep 17 00:00:00 2001 From: Jeremy-boo Date: Sun, 11 Dec 2022 17:13:54 +0800 Subject: [PATCH] feat: Refactor the harbor arm build script according to the main branch. Signed-off-by: Jeremy-boo --- .github/workflows/CI.yml | 263 +++++- Makefile | 152 +--- VERSION | 2 +- tests/.gitignore | 4 - tests/ca.crt | 1 - tests/ci/api_common_install.sh | 78 -- tests/ci/api_run.sh | 64 -- tests/ci/build_util.sh | 28 - tests/ci/clean.sh | 50 +- tests/ci/conformance_test.sh | 25 - tests/ci/distro_installer.sh | 7 - tests/ci/ui_ut_run.sh | 9 - tests/ci/ut_install.sh | 38 - tests/ci/ut_run.sh | 20 - tests/configharbor.py | 48 -- tests/coverage4gotest.sh | 38 - tests/docker-compose.test.yml | 29 - tests/generateCerts.sh | 49 -- tests/harbor_ca.crt | 32 - tests/harbor_ca.key | 52 -- tests/hostcfg.sh | 17 - tests/integration.sh | 224 ----- tests/ldap_test.ldif | 792 ------------------ tests/ldapprepare.sh | 28 - tests/notarytest.sh | 19 - tests/private_key.pem | 51 -- tests/pushimage.sh | 16 - tests/reg_config.yml | 18 - tests/showtime.sh | 13 - tests/startuptest.sh | 28 - tests/swaggerchecker.sh | 42 - tests/testprepare.sh | 21 - tests/userlogintest.sh | 20 - tests/validatecontainers.sh | 7 - tools/migrate_chart/Dockerfile | 32 - tools/migrate_chart/Readme.md | 36 - tools/migrate_chart/migrate_chart.py | 107 --- tools/migrate_chart/migrate_chart.sh | 9 - tools/mockery/Dockerfile | 33 - tools/spectral/Dockerfile | 19 - tools/spectral/functions/requireRequestId.js | 13 - tools/swagger/Dockerfile | 19 - tools/swagger/templates/README.md | 311 ------- tools/swagger/templates/client/client.gotmpl | 92 -- tools/swagger/templates/client/facade.gotmpl | 83 -- tools/swagger/templates/server/builder.gotmpl | 466 ----------- .../templates/server/configureapi.gotmpl | 210 ----- .../swagger/templates/server/responses.gotmpl | 271 ------ tools/swagger/templates/server/server.gotmpl | 9 - 49 files changed, 276 insertions(+), 3719 deletions(-) delete mode 100644 tests/.gitignore delete mode 100644 tests/ca.crt delete mode 100755 tests/ci/api_common_install.sh delete mode 100755 tests/ci/api_run.sh delete mode 100644 tests/ci/build_util.sh delete mode 100755 tests/ci/conformance_test.sh delete mode 100755 tests/ci/distro_installer.sh delete mode 100755 tests/ci/ui_ut_run.sh delete mode 100755 tests/ci/ut_install.sh delete mode 100755 tests/ci/ut_run.sh delete mode 100644 tests/configharbor.py delete mode 100755 tests/coverage4gotest.sh delete mode 100644 tests/docker-compose.test.yml delete mode 100755 tests/generateCerts.sh delete mode 100644 tests/harbor_ca.crt delete mode 100644 tests/harbor_ca.key delete mode 100755 tests/hostcfg.sh delete mode 100755 tests/integration.sh delete mode 100644 tests/ldap_test.ldif delete mode 100755 tests/ldapprepare.sh delete mode 100755 tests/notarytest.sh delete mode 100644 tests/private_key.pem delete mode 100755 tests/pushimage.sh delete mode 100644 tests/reg_config.yml delete mode 100755 tests/showtime.sh delete mode 100755 tests/startuptest.sh delete mode 100755 tests/swaggerchecker.sh delete mode 100755 tests/testprepare.sh delete mode 100755 tests/userlogintest.sh delete mode 100755 tests/validatecontainers.sh delete mode 100644 tools/migrate_chart/Dockerfile delete mode 100644 tools/migrate_chart/Readme.md delete mode 100644 tools/migrate_chart/migrate_chart.py delete mode 100644 tools/migrate_chart/migrate_chart.sh delete mode 100644 tools/mockery/Dockerfile delete mode 100644 tools/spectral/Dockerfile delete mode 100644 tools/spectral/functions/requireRequestId.js delete mode 100644 tools/swagger/Dockerfile delete mode 100644 tools/swagger/templates/README.md delete mode 100644 tools/swagger/templates/client/client.gotmpl delete mode 100644 tools/swagger/templates/client/facade.gotmpl delete mode 100644 tools/swagger/templates/server/builder.gotmpl delete mode 100644 tools/swagger/templates/server/configureapi.gotmpl delete mode 100644 tools/swagger/templates/server/responses.gotmpl delete mode 100644 tools/swagger/templates/server/server.gotmpl diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 6244b37..1444169 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -13,21 +13,91 @@ env: REDIS_HOST: localhost REG_VERSION: v2.7.1-patch-2819-2553 UI_BUILDER_VERSION: 1.6.0 + GO111MODULE: "on" + GOPROXY: "https://proxy.golang.org,direct" + GOCACHE: "/root/.cache/go-build" + GOROOT: "/usr/local/go" + GOPATH: "/root/go" + ARCH: arm64 on: pull_request: jobs: + UTTEST: + env: + UTTEST: true + runs-on: [self-hosted, linux, ARM64, ci] + #- self-hosted + timeout-minutes: 100 + steps: + - name: Set up Go 1.19 + uses: actions/setup-go@v1 + with: + go-version: 1.19.3 + id: go + - uses: actions/checkout@v2 + with: + path: src/github.com/goharbor/harbor-arm + - name: setup env + run: | + cd src/github.com/goharbor/harbor-arm + sudo make download + pwd + go env + echo "GOPATH=$(go env GOPATH):$GITHUB_WORKSPACE" >> $GITHUB_ENV + echo "$(go env GOPATH)/bin" >> $GITHUB_PATH + echo "TOKEN_PRIVATE_KEY_PATH=${GITHUB_WORKSPACE}/src/github.com/goharbor/harbor-arm/tests/private_key.pem" >> $GITHUB_ENV + shell: bash + - name: before_install + run: | + set -x + cd src/github.com/goharbor/harbor-arm + pwd + env + #sudo apt install -y xvfb + #xvfb-run ls + sudo pip3 install docker-compose + IP=`hostname -I | awk '{print $1}'` + echo '{"insecure-registries" : ["'$IP':5000"]}' | sudo tee /etc/docker/daemon.json + echo "IP=$IP" >> $GITHUB_ENV + sudo cp ./tests/harbor_ca.crt /usr/local/share/ca-certificates/ + sudo update-ca-certificates + sudo service docker restart + - name: install + run: | + cd src/github.com/goharbor/harbor-arm/src/github.com/goharbor/harbor + env + df -h + bash ./tests/showtime.sh ./tests/ci/ut_install.sh $ARCH + - name: script + run: | + echo IP: $IP + df -h + cd src/github.com/goharbor/harbor-arm/src/github.com/goharbor/harbor + bash ./tests/showtime.sh ./tests/ci/ut_run.sh $IP + df -h + - name: Codecov For BackEnd + uses: codecov/codecov-action@v1 + with: + file: ./src/github.com/goharbor/harbor-arm/profile.cov + flags: unittests + - name: clean + run: | + set -x + cd src/github.com/goharbor/harbor-arm + bash ./tests/ci/clean.sh + APITEST_DB: env: APITEST_DB: true - runs-on: [self-hosted, linux, ARM64, ci] + runs-on: [self-hosted, linux, ARM64, ci, debug] timeout-minutes: 100 steps: - - name: Set up Go 1.15 + - name: Set up Go 1.19 uses: actions/setup-go@v1 with: - go-version: 1.15.12 + go-version: 1.19.3 id: go - uses: actions/checkout@v2 with: @@ -35,7 +105,7 @@ jobs: - name: setup env run: | cd src/github.com/goharbor/harbor-arm - sudo make download compile_redis prepare_arm_data pre_update + sudo make download pwd go env echo "GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }}" >> $GITHUB_ENV @@ -62,7 +132,7 @@ jobs: env df -h docker system prune -a -f - bash ./tests/showtime.sh ./tests/ci/api_common_install.sh $IP DB + bash ./tests/showtime.sh ./tests/ci/api_common_install.sh $IP DB $ARCH - name: script run: | cd src/github.com/goharbor/harbor-arm/src/github.com/goharbor/harbor @@ -73,6 +143,187 @@ jobs: - name: clean run: | set -x + cd src/github.com/goharbor/harbor-arm + bash ./tests/ci/clean.sh + + APITEST_DB_PROXY_CACHE: + env: + APITEST_DB: true + runs-on: [self-hosted, linux, ARM64, ci] + #- self-hosted + timeout-minutes: 100 + steps: + - name: Set up Go 1.19 + uses: actions/setup-go@v1 + with: + go-version: 1.19.3 + id: go + - uses: actions/checkout@v2 + with: + path: src/github.com/goharbor/harbor-arm + - name: setup env + run: | + cd src/github.com/goharbor/harbor-arm + sudo make download + pwd + go env + echo "GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }}" >> $GITHUB_ENV + echo "GOPATH=$(go env GOPATH):$GITHUB_WORKSPACE" >> $GITHUB_ENV + echo "$(go env GOPATH)/bin" >> $GITHUB_PATH + echo "TOKEN_PRIVATE_KEY_PATH=${GITHUB_WORKSPACE}/src/github.com/goharbor/harbor-arm/tests/private_key.pem" >> $GITHUB_ENV + IP=`hostname -I | awk '{print $1}'` + echo "IP=$IP" >> $GITHUB_ENV + shell: bash + - name: install + run: | + cd src/github.com/goharbor/harbor-arm/src/github.com/goharbor/harbor + env + df -h + docker system prune -a -f + bash ./tests/showtime.sh ./tests/ci/api_common_install.sh $IP DB $ARCH + - name: script + run: | cd src/github.com/goharbor/harbor-arm/src/github.com/goharbor/harbor - bash ./tests/ci/clean.sh $PWD + echo IP: $IP + df -h + bash ./tests/showtime.sh ./tests/ci/api_run.sh PROXY_CACHE $IP + df -h + - name: clean + run: | + set -x + cd src/github.com/goharbor/harbor-arm + bash ./tests/ci/clean.sh + + APITEST_LDAP: + env: + APITEST_LDAP: true + runs-on: [self-hosted, linux, ARM64, ci] + #- self-hosted + timeout-minutes: 100 + steps: + - name: Set up Go 1.19 + uses: actions/setup-go@v1 + with: + go-version: 1.19.3 + id: go + - uses: actions/checkout@v2 + with: + path: src/github.com/goharbor/harbor-arm + - name: setup env + run: | + cd src/github.com/goharbor/harbor-arm + sudo make download + pwd + go env + echo "GOPATH=$(go env GOPATH):$GITHUB_WORKSPACE" >> $GITHUB_ENV + echo "$(go env GOPATH)/bin" >> $GITHUB_PATH + echo "TOKEN_PRIVATE_KEY_PATH=${GITHUB_WORKSPACE}/src/github.com/goharbor/harbor-arm/tests/private_key.pem" >> $GITHUB_ENV + IP=`hostname -I | awk '{print $1}'` + echo "IP=$IP" >> $GITHUB_ENV + shell: bash + - name: install + run: | + cd src/github.com/goharbor/harbor-arm/src/github.com/goharbor/harbor + env + df -h + bash ./tests/showtime.sh ./tests/ci/api_common_install.sh $IP LDAP $ARCH + - name: script + run: | + echo IP: $IP + df -h + cd src/github.com/goharbor/harbor-arm/src/github.com/goharbor/harbor + bash ./tests/showtime.sh ./tests/ci/api_run.sh LDAP $IP + df -h + - name: clean + run: | + set -x + cd src/github.com/goharbor/harbor-arm + bash ./tests/ci/clean.sh + + OFFLINE: + env: + OFFLINE: true + runs-on: [self-hosted, linux, ARM64, ci] + #- self-hosted + timeout-minutes: 100 + steps: + - name: Set up Go 1.15 + uses: actions/setup-go@v1 + with: + go-version: 1.15.12 + id: go + - uses: actions/checkout@v2 + with: + path: src/github.com/goharbor/harbor-arm + - name: setup env + run: | + cd src/github.com/goharbor/harbor-arm + sudo make download + pwd + docker version + go env + echo "GOPATH=$(go env GOPATH):$GITHUB_WORKSPACE" >> $GITHUB_ENV + echo "$(go env GOPATH)/bin" >> $GITHUB_PATH + echo "TOKEN_PRIVATE_KEY_PATH=${GITHUB_WORKSPACE}/src/github.com/goharbor/harbor-arm/tests/private_key.pem" >> $GITHUB_ENV + shell: bash + - name: before_install + run: | + set -x + cd src/github.com/goharbor/harbor-arm + pwd + env + df -h + #sudo apt install -y xvfb + #xvfb-run ls + IP=`hostname -I | awk '{print $1}'` + echo '{"insecure-registries" : ["'$IP':5000"]}' | sudo tee /etc/docker/daemon.json + echo "IP=$IP" >> $GITHUB_ENV + sudo cp ./tests/harbor_ca.crt /usr/local/share/ca-certificates/ + sudo update-ca-certificates + sudo service docker restart + - name: script + run: | + echo IP: $IP + df -h + cd src/github.com/goharbor/harbor-arm/src/github.com/goharbor/harbor + bash ./tests/showtime.sh ./tests/ci/distro_installer.sh $ARCH + df -h + - name: clean + run: | + set -x + cd src/github.com/goharbor/harbor-arm + bash ./tests/ci/clean.sh + + UI_UT: + env: + UI_UT: true + runs-on: [self-hosted, linux, ARM64, ci] + #- self-hosted + timeout-minutes: 100 + steps: + - uses: actions/setup-node@v1 + with: + node-version: '16.15.0' + - uses: actions/checkout@v2 + with: + path: src/github.com/goharbor/harbor-arm + - name: script + run: | + echo IP: $IP + df -h + cd src/github.com/goharbor/harbor-arm + sudo make download + cd src/github.com/goharbor/harbor + bash ./tests/showtime.sh ./tests/ci/ui_ut_run.sh + df -h + - name: Codecov For UI + uses: codecov/codecov-action@v1 + with: + file: ./src/github.com/goharbor/harbor-arm/src/github.com/goharbor/harbor/src/portal/coverage/lcov.info + flags: unittests + - name: clean + run: | + set -x + cd src/github.com/goharbor/harbor-arm + bash ./tests/ci/clean.sh \ No newline at end of file diff --git a/Makefile b/Makefile index 8b5095b..e064b0c 100644 --- a/Makefile +++ b/Makefile @@ -17,177 +17,31 @@ # Targets: # # all: -# _update_makefile: replace goharbor/harbor's makefile for build harbor-arm. -# -# _update_make_photon_makefile: replace goharbor/harbor's photon makefile. -# -# _update_chartserver: replace goharbor/harbor's chartserver -# -# _update_registry: replace goharbor/harbor's registry -# -# _update_trivy-adapter: replace goharbor/harbor's trivy-adapter -# -# _update_portal: replace goharbor/harbor's portal -# -# _update_notary: replace goharbor/harbor's notary -# -# pre_update: # # download: # # compile: # -# build_base_image: -# -# build: BUILDPATH=$(CURDIR)/src/github.com/goharbor/harbor -# default goharbor/harbor make path -HARBOR_MAKEFILE_PATH=$(BUILDPATH)/Makefile -HARBOR_PHOTON_MAKEFILE_PATH=$(BUILDPATH)/make/photon/Makefile -HARBOR_PHOTON_CHARTSERVER_COMPILE_PATH=$(BUILDPATH)/make/photon/chartserver/compile.sh -HARBOR_PHOTON_REGISTRY_DOCKERFILE_PATH=$(BUILDPATH)/make/photon/registry/Dockerfile.binary -HARBOR_PHOTON_TRIVY-ADAPTER_DOCKERFILE_PATH=$(BUILDPATH)/make/photon/trivy-adapter/Dockerfile.binary -HARBOR_PHOTON_NOTARY_DOCKERFILE_PATH=$(BUILDPATH)/make/photon/notary/binary.Dockerfile -HARBOR_PHOTON_NOTARY_BUILDER_PATH=$(BUILDPATH)/make/photon/notary/builder -HARBOR_PHOTON_PORTAL_DOCKERFILE_PATH=$(BUILDPATH)/make/photon/portal/Dockerfile -HARBOR_PHOTON_EXPORTER_PATH=$(BUILDPATH)/make/photon/exporter/Dockerfile -HARBOR_PUSHIMAGE_PATH=$(BUILDPATH)/make/pushimage.sh - # download goharbor/harbor parammeters -HARBOR_SOURCE_URL=https://github.com/goharbor/harbor.git +HARBOR_SOURCE_URL=https://github.com/Jeremy-boo/harbor.git SRCPATH=src/github.com/goharbor/harbor -HARBOR_TAG=release-2.3.0 +HARBOR_TAG=feat/harbor_arm_build_make_to_main # makefile path MAKEPATH=$(BUILDPATH)/make -# make target -MAKE_COMPILE=compile -MAKE_BUILD_BASE=build_base_docker -MAKE_ONLINE=package_online -MAKE_OFFLINE=package_offline -MAKE_BUILD=build - -# parameters -BUILD_PG96=true -DEVFLAG=true -BUILDBIN=true - -# package -TARCMD=$(shell which tar) -ZIPCMD=$(shell which gzip) -DOCKERIMGFILE=harbor-arm -HARBORPKG=harbor-arm - - -# for docker image tag -VERSIONTAG=dev-arm -BASEIMAGETAG=dev-arm -BUILD_BASE=true -PUSHBASEIMAGE=false -BASEIMAGENAMESPACE=goharbor - -# #input true/false only -PULL_BASE_FROM_DOCKERHUB=true - -# sed location -SEDCMD=$(shell which sed) -SEDCMDI=$(SEDCMD) -i -ifeq ($(shell uname),Darwin) - SEDCMDI=$(shell which gsed) -i -endif - -# dockerhub user -REGISTRYUSER= -REGISTRYPASSWORD= - -_update_makefile: - @echo "update goharbor makefile" - @$(SEDCMDI) 's/--rm/--rm --env CGO_ENABLED=0 --env GOOS=linux --env GOARCH=arm64/g' $(HARBOR_MAKEFILE_PATH); - @$(SEDCMDI) 's/$$(DOCKERBUILD)/docker buildx build --platform linux\/arm64 --progress plain --output=type=docker/g' $(HARBOR_MAKEFILE_PATH); - @$(SEDCMDI) 's/gen_apis: lint_apis/gen_apis:/g' $(HARBOR_MAKEFILE_PATH); - @$(SEDCMDI) 's/_Linux-64bit.tar.gz/_Linux-ARM64.tar.gz/g' $(HARBOR_MAKEFILE_PATH); - @$(SEDCMDI) 's/_Linux_x86_64.tar.gz/_Linux_arm64.tar.gz/g' $(HARBOR_MAKEFILE_PATH); - @$(SEDCMDI) 's/VERSIONTAG=dev/VERSIONTAG=dev-arm/g' $(HARBOR_MAKEFILE_PATH); - @$(SEDCMDI) 's/BASEIMAGETAG=dev/BASEIMAGETAG=dev-arm/g' $(HARBOR_MAKEFILE_PATH); - @$(SEDCMDI) 's/BUILD_PG96=true/BUILD_PG96=false/g' $(HARBOR_MAKEFILE_PATH); - - -_update_make_photon_makefile: - @echo "update goharbor photon makefile" - @$(SEDCMDI) 's/$(DOCKERCMD) build/$(DOCKERCMD) buildx build --platform linux\/arm64 --progress plain --output=type=docker/' $(HARBOR_PHOTON_MAKEFILE_PATH) - @$(SEDCMDI) '219 a \ \ \ \ \ \ \ \ docker buildx prune -f ; \\' $(HARBOR_PHOTON_MAKEFILE_PATH) - -_update_chartserver: - @echo "update goharbor chartserver compile.sh" - @$(SEDCMDI) 's/go build -a/GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -a/g' $(HARBOR_PHOTON_CHARTSERVER_COMPILE_PATH) - -_update_registry: - @echo "update goharbor registry Dockerfile.binary" - @$(SEDCMDI) 's/CGO_ENABLED=0/GOOS=linux GOARCH=arm64 CGO_ENABLED=0/g' $(HARBOR_PHOTON_REGISTRY_DOCKERFILE_PATH) - -_update_trivy-adapter: - @echo "update goharbor trivy-adapter Dockerfile.binary" - @$(SEDCMDI) 's/CGO_ENABLED=0/GOARCH=arm64 CGO_ENABLED=0/g' $(HARBOR_PHOTON_TRIVY-ADAPTER_DOCKERFILE_PATH) - -_update_portal: - @echo "update goharbor portal Dockerfile" - @$(SEDCMDI) 's/node:15.4.0/--platform=$${BUILDPLATFORM:-linux\/amd64} node:15.4.0/g' $(HARBOR_PHOTON_PORTAL_DOCKERFILE_PATH); - @$(SEDCMDI) "s/'node_modules\/@angular\/cli\/bin\/ng'/.\/node_modules\/@angular\/cli\/bin\/ng/g" $(HARBOR_PHOTON_PORTAL_DOCKERFILE_PATH) - -_update_notary: - @echo "update goharbor notary binary.Dockerfile" - @$(SEDCMDI) '8 a ENV CGO_ENABLED 0 \nENV GOOS linux \nENV GOARCH arm64' $(HARBOR_PHOTON_NOTARY_DOCKERFILE_PATH) - @echo "update goharbor notary builder" - @$(SEDCMDI) 's/docker build/docker buildx build --platform linux\/arm64 --progress plain --output=type=docker/g' $(HARBOR_PHOTON_NOTARY_BUILDER_PATH) - -_update_exporter: - @echo "update goharbor exporter Dockerfile" - @$(SEDCMDI) 's/ENV GOARCH=amd64/ENV GOARCH=arm64/g' $(HARBOR_PHOTON_EXPORTER_PATH) - - - - -pre_update: _update_makefile _update_make_photon_makefile _update_chartserver _update_registry _update_trivy-adapter _update_notary _update_portal _update_exporter - # downlaod goharbor/harbor source code download: $(shell git clone --branch $(HARBOR_TAG) $(HARBOR_SOURCE_URL) $(SRCPATH)) @echo "download goharbor/harbor source code success" - -# Arm data replacement before building harbor arm -prepare_arm_data: - @echo "copy tools fodler to goharbor/harbor/tools fodler" - cp -r $(CURDIR)/tools/. $(BUILDPATH)/tools/ - @echo "copy tests bash fodler to goharbor/harbor/tests fodler" - cp -r $(CURDIR)/tests/. $(BUILDPATH)/tests/ # Rebuild the redis binary file in order to avoid the page-size problem when running on the arm64 machine compile_redis: @echo $(CURDIR) cd $(CURDIR)/redis && $(CURDIR)/redis/rpm_builder.sh && cd - ; @echo "copy redis file to goharbor harbor photon redis fodler" - cp -r $(CURDIR)/redis/. $(BUILDPATH)/make/photon/redis - - -compile: - cd $(SRCPATH) && make -f Makefile $(MAKE_COMPILE) - -build_base_image: - cd $(SRCPATH) && make -f Makefile $(MAKE_BUILD_BASE) \ - -e BASEIMAGETAG=$(BASEIMAGETAG) -e BASEIMAGENAMESPACE=$(BASEIMAGENAMESPACE) \ - -e REGISTRYUSER=$(REGISTRYUSER) -e REGISTRYPASSWORD=$(REGISTRYPASSWORD) -e BUILD_PG96=$(BUILD_PG96) - -package_online: - cd $(SRCPATH) && make -f Makefile $(MAKE_ONLINE) - -.PHONY: build -build: - @echo "build harbor-arm image" - cd $(SRCPATH) && make -f Makefile $(MAKE_BUILD) -e DEVFLAG=$(DEVFLAG) \ - -e REGISTRYUSER=$(REGISTRYUSER) -e REGISTRYPASSWORD=$(REGISTRYPASSWOR) \ - -e PULL_BASE_FROM_DOCKERHUB=$(PULL_BASE_FROM_DOCKERHUB) \ - -e BUILD_BASE=$(BUILD_BASE) -e VERSIONTAG=$(VERSIONTAG) \ No newline at end of file + cp -r $(CURDIR)/redis/. $(BUILDPATH)/make/photon/redis \ No newline at end of file diff --git a/VERSION b/VERSION index b1d18bc..9001211 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v2.3.0 +dev \ No newline at end of file diff --git a/tests/.gitignore b/tests/.gitignore deleted file mode 100644 index 5e558a3..0000000 --- a/tests/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -*.crt -*.key -*.csr -extfile.cnf diff --git a/tests/ca.crt b/tests/ca.crt deleted file mode 100644 index ed71ba7..0000000 --- a/tests/ca.crt +++ /dev/null @@ -1 +0,0 @@ -test for ca.crt. diff --git a/tests/ci/api_common_install.sh b/tests/ci/api_common_install.sh deleted file mode 100755 index a518ad0..0000000 --- a/tests/ci/api_common_install.sh +++ /dev/null @@ -1,78 +0,0 @@ -#!/bin/bash -set -x - -set +e -sudo rm -fr /data/* -sudo mkdir -p /data -DIR="$(cd "$(dirname "$0")" && pwd)" - -set -e -if [ -z "$1" ]; then echo no ip specified; exit 1;fi -# prepare cert ... -sudo ./tests/generateCerts.sh $1 - -python --version -pip -V -cat /etc/issue -cat /proc/version -sudo -H pip install --ignore-installed urllib3 chardet requests --upgrade -python --version - -#---------------Set DNS for docker v20-----------------------# -# In docker v20, it fixed an issue named "Wrong resolv.conf -# used on Ubuntu 19", this fix caused DNS solve problem -# in container. So the current work round is read DNS server -# from system and set the value in /etc/docker/daemon.json. - -# ip addr -# docker_config_file="/etc/docker/daemon.json" -# dns_ip_string=$(netplan ip leases eth0 | grep -i dns | awk -F = '{print $2}' | tr " " "\n" | sed 's/,/","/g') -# dns=[\"${dns_ip_string}\"] -# echo dns=${dns} - -# cat $docker_config_file -# if [ -f $docker_config_file ];then -# if [ $(cat /etc/docker/daemon.json |grep \"dns\" |wc -l) -eq 0 ];then -# sudo sed "s/}/,\n \"dns\": $dns\n}/" -i $docker_config_file -# fi -# else -# echo "{\"dns\": $dns}" > $docker_config_file -# fi -# cat $docker_config_file -# sudo systemctl stop docker -# sudo systemctl start docker -# sleep 2 -#------------------------------------------------------------# - -sudo ./tests/hostcfg.sh - -if [ "$2" = 'LDAP' ]; then - cd tests && sudo ./ldapprepare.sh && cd .. -fi - -if [ $GITHUB_TOKEN ]; -then - sed "s/# github_token: xxx/github_token: $GITHUB_TOKEN/" -i make/harbor.yml -fi - -sed "s|# metric:|metric:|" -i make/harbor.yml -sed "s|# enabled: false| enabled: true|" -i make/harbor.yml -sed "s|# port: 9090| port: 9090|" -i make/harbor.yml -sed "s|# path: /metrics| path: /metrics|" -i make/harbor.yml - -# build -sudo make compile build prepare COMPILETAG=compile_golangimage GOBUILDTAGS="include_oss include_gcs" BUILDBIN=true NOTARYFLAG=true TRIVYFLAG=true CHARTFLAG=true GEN_TLS=true PULL_BASE_FROM_DOCKERHUB=false - -# set the debugging env -echo "GC_TIME_WINDOW_HOURS=0" | sudo tee -a ./make/common/config/core/env - -# harbor-arm 添加start target -sudo make start - -# waiting 5 minutes to start -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 - docker ps -done diff --git a/tests/ci/api_run.sh b/tests/ci/api_run.sh deleted file mode 100755 index 6bca05e..0000000 --- a/tests/ci/api_run.sh +++ /dev/null @@ -1,64 +0,0 @@ -#!/bin/bash -set -x - -#source gskey.sh - -sudo gsutil version -l - -harbor_logs_bucket="harbor-ci-logs" -# GC credentials -#keyfile="/home/travis/harbor-ci-logs.key" -#botofile="/home/travis/.boto" -#echo -en $GS_PRIVATE_KEY > $keyfile -#sudo 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 -DIR="$(cd "$(dirname "$0")" && pwd)" -E2E_IMAGE="goharbor/harbor-e2e-engine:3.0.0-api-arm" - -# GS util -function uploader { - sudo gsutil cp $1 gs://$2/$1 - sudo gsutil acl ch -u AllUsers:R gs://$2/$1 -} - -set +e - -docker ps -# run db auth api cases -if [ "$1" = 'DB' ]; then - docker run -i --privileged -v $DIR/../../:/drone -v $DIR/../:/ca -w /drone $E2E_IMAGE robot --exclude proxy_cache -v DOCKER_USER:${DOCKER_USER} -v DOCKER_PWD:${DOCKER_PWD} -v ip:$2 -v ip1: -v http_get_ca:false -v HARBOR_PASSWORD:Harbor12345 /drone/tests/robot-cases/Group1-Nightly/Setup.robot /drone/tests/robot-cases/Group0-BAT/API_DB.robot -elif [ "$1" = 'PROXY_CACHE' ]; then - docker run -i --privileged -v $DIR/../../:/drone -v $DIR/../:/ca -w /drone $E2E_IMAGE robot --include setup --include proxy_cache -v DOCKER_USER:${DOCKER_USER} -v DOCKER_PWD:${DOCKER_PWD} -v ip:$2 -v ip1: -v http_get_ca:false -v HARBOR_PASSWORD:Harbor12345 /drone/tests/robot-cases/Group1-Nightly/Setup.robot /drone/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 \ - ldap_url=ldap://$IP \ - ldap_search_dn=cn=admin,dc=example,dc=com \ - ldap_search_password=admin \ - ldap_base_dn=dc=example,dc=com \ - ldap_uid=cn - docker run -i --privileged -v $DIR/../../:/drone -v $DIR/../:/ca -w /drone $E2E_IMAGE robot -v DOCKER_USER:${DOCKER_USER} -v DOCKER_PWD:${DOCKER_PWD} -v ip:$2 -v ip1: -v http_get_ca:false -v HARBOR_PASSWORD:Harbor12345 /drone/tests/robot-cases/Group1-Nightly/Setup.robot /drone/tests/robot-cases/Group0-BAT/API_LDAP.robot -else - rc=999 -fi -rc=$? -## --------------------------------------------- Upload Harbor CI Logs ------------------------------------------- -timestamp=$(date +%s) -outfile="integration_logs_$timestamp$TRAVIS_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 diff --git a/tests/ci/build_util.sh b/tests/ci/build_util.sh deleted file mode 100644 index bec07d9..0000000 --- a/tests/ci/build_util.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash -set -x - -set -e - -function uploader { - gsutil cp $1 gs://$2/$1 - gsutil -D setacl public-read gs://$2/$1 &> /dev/null -} - -function publishImage { - echo "Publishing images to Docker Hub..." - echo "The images on the host:" - # for master, will use 'dev' as the tag name - # for release-*, will use 'release-*-dev' as the tag name, like release-v1.8.0-dev - if [[ $1 == "master" ]]; then - image_tag=dev - fi - if [[ $1 == "release-"* ]]; then - image_tag=$2-dev - fi - # rename the images with tag "dev" and push to Docker Hub - docker images - docker login -u $3 -p $4 - docker images | grep goharbor | grep -v "\-base" | sed -n "s|\(goharbor/[-._a-z0-9]*\)\s*\(.*$2\).*|docker tag \1:\2 \1:$image_tag;docker push \1:$image_tag|p" | bash - echo "Images are published successfully" - docker images -} \ No newline at end of file diff --git a/tests/ci/clean.sh b/tests/ci/clean.sh index 35cd82b..4da1581 100644 --- a/tests/ci/clean.sh +++ b/tests/ci/clean.sh @@ -1,45 +1,25 @@ #!/bin/bash set -x -# harbor make path for harbor-arm -harbor_arm_path="$0/make" +# stop running containers +docker stop $(docker ps -aq) -# docker-compose file name -docker_compose_file="docker-compose.yml" +# delete all containers +docker rm $(docker ps -aq) -# docker-compose file path -docker_compose_path=$harbor_arm_path/$docker_compose_file +# Clean up the image on the host +docker system prune -a -f -# Determine whether there is a deployed harbor process -if [ $(docker ps -a | grep -c "goharbor") -gt 1 ]; then - if [ -f "$docker_compose_path" ]; then - echo "Stop harbor process from docker-compose.yaml" - cd $harbor_arm_path - docker-compose down - else - echo "No docker-compose.yaml file" - fi -else - echo "No harbor process" -fi - -# Determine whether the automated test process remains -if [ $(docker ps -a | grep -c "goharbor/harbor-e2e-engine") -gt 0 ]; then - docker rm $(docker ps -qa) -else - echo "No harbor process" -fi # Delete cache file "/data" -harbor_cache_path="/data" -if [ -d "$harbor_cache_path" ]; then - echo "delete harbor cache path $harbor_cache_path" - rm -rf $harbor_cache_path/* +harbor_install_cache="/data" +if [ -d "$harbor_install_cache" ]; then + echo "delete harbor install cache path $harbor_install_cache" + rm -rf $harbor_install_cache fi -# Delete the harbor-arm source directory -# harbor_arm_source_path="/root/actions-runner/harbor-arm-ci/harbor-arm/harbor-arm" -# if [ -d "$harbor_arm_source_path" ]; then -# echo "delete harbor source code path $harbor_arm_source_path" -# rm -rf $harbor_arm_source_path -# fi \ No newline at end of file +harbor_cache="/harbor" +if [ -d "$harbor_cache" ]; then + echo "delete harbor cache path $harbor_cache" + rm -rf $harbor_cache +fi diff --git a/tests/ci/conformance_test.sh b/tests/ci/conformance_test.sh deleted file mode 100755 index 07368f3..0000000 --- a/tests/ci/conformance_test.sh +++ /dev/null @@ -1,25 +0,0 @@ -set -e - -echo "get the conformance testing code..." -git clone https://github.com/opencontainers/distribution-spec.git - -echo "create testing project" -STATUS=$(curl -w '%{http_code}' -H 'Content-Type: application/json' -H 'Accept: application/json' -X POST -u "admin:Harbor12345" -s --insecure "https://$IP/api/v2.0/projects" --data '{"project_name":"conformance","metadata":{"public":"false"},"storage_limit":-1}') -if [ $STATUS -ne 201 ]; then - exit 1 -fi - -echo "run conformance test..." -export OCI_ROOT_URL="https://$1" -export OCI_NAMESPACE="conformance/testrepo" -export OCI_USERNAME="admin" -export OCI_PASSWORD="Harbor12345" -export OCI_DEBUG="true" - -export OCI_TEST_PUSH=1 -export OCI_TEST_PULL=1 -export OCI_TEST_CONTENT_DISCOVERY=1 -export OCI_TEST_CONTENT_MANAGEMENT=1 - -cd ./distribution-spec/conformance -go test . \ No newline at end of file diff --git a/tests/ci/distro_installer.sh b/tests/ci/distro_installer.sh deleted file mode 100755 index ec24cf3..0000000 --- a/tests/ci/distro_installer.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash -set -x - -set -e - -sudo make package_online GOBUILDTAGS="include_oss include_gcs" VERSIONTAG=dev-travis PKGVERSIONTAG=dev-travis UIVERSIONTAG=dev-travis GOBUILDIMAGE=golang:1.15.12 COMPILETAG=compile_golangimage BUILDBIN=true NOTARYFLAG=true CHARTFLAG=true TRIVYFLAG=true HTTPPROXY= -sudo make package_offline GOBUILDTAGS="include_oss include_gcs" VERSIONTAG=dev-travis PKGVERSIONTAG=dev-travis UIVERSIONTAG=dev-travis GOBUILDIMAGE=golang:1.15.12 COMPILETAG=compile_golangimage BUILDBIN=true NOTARYFLAG=true CHARTFLAG=true TRIVYFLAG=true HTTPPROXY= diff --git a/tests/ci/ui_ut_run.sh b/tests/ci/ui_ut_run.sh deleted file mode 100755 index 805db34..0000000 --- a/tests/ci/ui_ut_run.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash -set -x -set -e - -cd ./src/portal -npm install -g -q --no-progress @angular/cli -npm install -g -q --no-progress karma -npm install -q --no-progress -npm run test && cd - \ No newline at end of file diff --git a/tests/ci/ut_install.sh b/tests/ci/ut_install.sh deleted file mode 100755 index 3feac29..0000000 --- a/tests/ci/ut_install.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash -set -x - -set -e - -sudo apt-get update && sudo apt-get install -y libldap2-dev -go get -d github.com/docker/distribution -go get -d github.com/docker/libtrust -go get -d github.com/lib/pq -go get golang.org/x/lint/golint -go get github.com/GeertJohan/fgt -go get github.com/dghubble/sling -go get github.com/stretchr/testify -go get golang.org/x/tools/cmd/cover -go get github.com/mattn/goveralls -go get -u github.com/client9/misspell/cmd/misspell -sudo service postgresql stop || echo no postgresql need to be stopped -sleep 2 - -sudo rm -rf /data/* -sudo -E env "PATH=$PATH" make go_check -sudo ./tests/hostcfg.sh -sudo ./tests/generateCerts.sh -sudo make build -e BUILDTARGET="_build_db _build_registry _build_prepare" -e PULL_BASE_FROM_DOCKERHUB=false -docker run --rm -v /:/hostfs:z goharbor/prepare:dev gencert -p /etc/harbor/tls/internal -sudo MAKEPATH=$(pwd)/make ./make/prepare -sudo mkdir -p "/data/redis" -sudo mkdir -p /etc/core/ca/ && sudo mv ./tests/ca.crt /etc/core/ca/ -sudo mkdir -p /harbor && sudo mv ./VERSION /harbor/UIVERSION -sudo ./tests/testprepare.sh - -cd tests && sudo ./ldapprepare.sh && cd .. -env -docker images -sudo sed -i 's/__version__/dev/g' ./make/docker-compose.test.yml -cat ./make/docker-compose.test.yml -sudo mkdir -p ./make/common/config/registry/ && sudo mv ./tests/reg_config.yml ./make/common/config/registry/config.yml -sudo mkdir -p /storage && sudo chown 10000:10000 -R /storage diff --git a/tests/ci/ut_run.sh b/tests/ci/ut_run.sh deleted file mode 100755 index 70860c9..0000000 --- a/tests/ci/ut_run.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash -set -x - -set -e - -export POSTGRESQL_HOST=$1 -export REGISTRY_URL=http://$1:5000 -export CHROME_BIN=chromium-browser -#export DISPLAY=:99.0 -#sh -e /etc/init.d/xvfb start - -sudo docker-compose -f ./make/docker-compose.test.yml up -d -sleep 10 -./tests/pushimage.sh -docker ps - -DIR="$(cd "$(dirname "$0")" && pwd)" -go test -race -i ./src/core ./src/jobservice -sudo -E env "PATH=$PATH" "POSTGRES_MIGRATION_SCRIPTS_PATH=$DIR/../../make/migrations/postgresql/" ./tests/coverage4gotest.sh -#goveralls -coverprofile=profile.cov -service=github || true \ No newline at end of file diff --git a/tests/configharbor.py b/tests/configharbor.py deleted file mode 100644 index a7c6c2e..0000000 --- a/tests/configharbor.py +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/python - -import argparse -import json -import requests -import sys - -parser = argparse.ArgumentParser() -parser.add_argument("-H", "--host", help="The Harbor server need to config") -parser.add_argument("-u", "--user", default="admin", help="The Harbor username") -parser.add_argument("-p", "--password", default="Harbor12345", help="The Harbor password") -parser.add_argument("-c", "--config", nargs='+', help="The configure settings =, it can take more than one configures") -args = parser.parse_args() -reqJson = {} -for item in args.config : - configs = item.split("=", 1) - key = configs[0].strip() - value = configs[1].strip() - if value.lower() in ['true', 'yes', '1'] : - reqJson[key] = True - elif value.lower() in ['false', 'no', '0'] : - reqJson[key] = False - elif value.isdigit() : - reqJson[key] = int(value) - else: - reqJson[key] = value - -# Sample Basic Auth Url with login values as username and password -url = "https://"+args.host+"/api/v2.0/configurations" -user = args.user -passwd = args.password - -# Make a request to the endpoint using the correct auth values -auth_values = (user, passwd) -session = requests.Session() -session.verify = False -data = json.dumps(reqJson) -headers = {'Content-type': 'application/json', 'Accept': 'text/plain'} -response = session.put(url, auth=auth_values, data=data, headers=headers) - -# Convert JSON to dict and print -if response.status_code == 200 : - print("Configure setting success") - print("values:"+data) - sys.exit(0) -else: - print("Failed with http return code:"+ str(response.status_code)) - sys.exit(1) diff --git a/tests/coverage4gotest.sh b/tests/coverage4gotest.sh deleted file mode 100755 index 223cf69..0000000 --- a/tests/coverage4gotest.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash -set -e -echo "mode: set" >>profile.cov - -deps="" - -# listDeps lists packages referenced by package in $1, -# excluding golang standard library and packages in -# direcotry vendor -function listDeps(){ - pkg=$1 - deps=$pkg - ds=$(echo $(go list -f '{{.Imports}}' $pkg) | sed 's/[][]//g') - for d in $ds - do - if echo $d | grep -q "github.com/goharbor/harbor" && echo $d | grep -qv "vendor" - then - deps="$deps,$d" - fi - done -} - -packages=$(go list ./... | grep -v -E 'vendor|tests|testing') -echo testing packages: $packages - -for package in $packages -do - listDeps $package - -# echo "DEBUG: testing package $package" - echo go test -race -v -cover -coverprofile=profile.tmp -coverpkg "$deps" $package - go test -race -v -cover -coverprofile=profile.tmp -coverpkg "$deps" $package - if [ -f profile.tmp ] - then - cat profile.tmp | tail -n +2 >> profile.cov - rm profile.tmp - fi -done diff --git a/tests/docker-compose.test.yml b/tests/docker-compose.test.yml deleted file mode 100644 index f8303df..0000000 --- a/tests/docker-compose.test.yml +++ /dev/null @@ -1,29 +0,0 @@ -version: '2' -services: - registry: - image: goharbor/registry-photon:__version__ - restart: always - volumes: - - /data/registry:/storage - - ./common/config/registry/:/etc/registry/ - - /etc/core/ca/ca.crt:/etc/registry/root.crt - ports: - - 5000:5000 - command: - ["serve", "/etc/registry/config.yml"] - postgres: - image: goharbor/harbor-db:__version__ - restart: always - volumes: - - /data/database:/var/lib/postgresql/data:z - env_file: - - ./common/config/db/env - ports: - - 5432:5432 - redis: - image: goharbor/redis-photon:__version__ - restart: always - volumes: - - /data/redis:/var/lib/redis - ports: - - 6379:6379 diff --git a/tests/generateCerts.sh b/tests/generateCerts.sh deleted file mode 100755 index 439f31c..0000000 --- a/tests/generateCerts.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env bash - -# These certs file is only for Harbor testing. -CN='127.0.0.1' - -IPV4_REGEX='((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])' -IPV6_REGEX='(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))' -TEMP_FILENAME='temp' -if [ ! -z "$1" ]; then CN=$1; fi -OPENSSLCNF= -DATA_VOL='/data' -CUR_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" - -for path in /etc/openssl/openssl.cnf /etc/ssl/openssl.cnf /usr/local/etc/openssl/openssl.cnf; do - if [[ -e ${path} ]]; then - OPENSSLCNF=${path} - fi -done -if [[ -z ${OPENSSLCNF} ]]; then - printf "Could not find openssl.cnf" - exit 1 -fi - -# Create CA certificate -# openssl req \ -# -newkey rsa:4096 -nodes -sha256 -keyout $CUR_DIR/harbor_ca.key \ -# -x509 -days 365 -out $CUR_DIR/harbor_ca.crt -subj '/C=CN/ST=PEK/L=Bei Jing/O=VMware/CN=HarborCA' - -# Generate a Certificate Signing Request -if [[ $CN =~ $IPV4_REGEX ]] || [[ $CN =~ $IPV6_REGEX ]] ; then -openssl req \ - -newkey rsa:4096 -nodes -sha256 -keyout $TEMP_FILENAME.key \ - -out $TEMP_FILENAME.csr -subj "/C=CN/ST=PEK/L=Bei Jing/O=VMware/CN=HarborManager" -echo subjectAltName = IP:$CN > extfile.cnf -else -openssl req \ - -newkey rsa:4096 -nodes -sha256 -keyout $TEMP_FILENAME.key \ - -out $TEMP_FILENAME.csr -subj "/C=CN/ST=PEK/L=Bei Jing/O=VMware/CN=$CN" -echo subjectAltName = DNS.1:$CN > extfile.cnf -fi - -# Generate the certificate of local registry host -openssl x509 -req -days 365 -sha256 -in $TEMP_FILENAME.csr -CA $CUR_DIR/harbor_ca.crt \ - -CAkey $CUR_DIR/harbor_ca.key -CAcreateserial -extfile extfile.cnf -out $TEMP_FILENAME.crt - -# Copy to harbor default location -mkdir -p $DATA_VOL/cert -cp $TEMP_FILENAME.crt $DATA_VOL/cert/server.crt -cp $TEMP_FILENAME.key $DATA_VOL/cert/server.key diff --git a/tests/harbor_ca.crt b/tests/harbor_ca.crt deleted file mode 100644 index 2410990..0000000 --- a/tests/harbor_ca.crt +++ /dev/null @@ -1,32 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFizCCA3OgAwIBAgIUSaokQeug3hbGAQwSPjjIl2eujIwwDQYJKoZIhvcNAQEL -BQAwVDELMAkGA1UEBhMCQ04xDDAKBgNVBAgMA1BFSzERMA8GA1UEBwwIQmVpIEpp -bmcxETAPBgNVBAoMCGdvaGFyYm9yMREwDwYDVQQDDAhIYXJib3JDQTAgFw0yMDA4 -MTIxMDUyNDNaGA8yMTIwMDcxOTEwNTI0M1owVDELMAkGA1UEBhMCQ04xDDAKBgNV -BAgMA1BFSzERMA8GA1UEBwwIQmVpIEppbmcxETAPBgNVBAoMCGdvaGFyYm9yMREw -DwYDVQQDDAhIYXJib3JDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB -AOZRZYkFmVBNabEU4cDaqa27k5+OuUHg1ooScCnbbBFxNB22/7CzXIWOWmFCVPjX -LwAV13u6pQkMMajDqPA/7ldz8ajYm9VTDg8/qGboa6aoNO4GLLdyili66GLmHpWk -B6/JZ3JaEvpz3948vMioGCupcBqExl8gHqrgsyjR9ueqS9le66/g1gDqVmSAU3pP -wKkwdRMOiQsxSL9TY/IXbCdUepslICeGLGjv4/UCtd9YUhiIRV97KsgKDn0BO29c -V+W3ICqmrP5lQCXyBP/IOen3sEhJPCU1neCY9c687JNRICeDXe2LbRRtAqB/nSW/ -u8cscy0XWzB8bpsvve6wHN2cBSkaMt90cv7Rq2ZK6tj19mps55xhJ2bl1LNCJl6b -U6SF/5zaf4/vAzIRhRZr2BaC9otg9SfP1yvTvAmZT/VyOhxGNPtjYuNkfoX5URCd -Y0w7itKEDfO605IisuLJFuIaYSLO85abR6j7C7MByVXzqTE5hautVeZz6HsM9lko -uvT1z4YZoaMT+0N2OGNpkQvyLNfK3gcV+rkHd5DAJgJXmg6UiexwQKIdR16/dydO -D7DzJL5SSKEnsBh056tjC584GaVicCU5YPUuPiHlwvDRDEKC+E440uLoB50Mq4L8 -8R9crYbIlXY/tQyyWF/QDmqrg31y5IF0pWrh98hZovyLAgMBAAGjUzBRMB0GA1Ud -DgQWBBS1J6WwrWROfVzRCgUkPxef35uenzAfBgNVHSMEGDAWgBS1J6WwrWROfVzR -CgUkPxef35uenzAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4ICAQCb -GdoS+NBd9+2cP5bKQEb7lexWtB93Z2UelVHa6YREot+guuMrVBgLboZcF1/ig2HD -MWiulR/CfC7kPmLSYVKDYWZbWEpZQhS6v+JyZAI1cYlSGtqeLqn5dpiQvv99vjrr -aXO5wke4CuY6tjU6sNCasi9H5W7OIE9BFlaJkIy8xJ3AxjDJZCjKa+alPWtJxFI+ -LsJfDfLRSxDN6XOCXIM6P3CMVv3zcnuObCzp5CJeiT/04ywjZBJB0wlDUxk7o+yX -cO2TPG87MK8mVzQ7/Zkg8/QVsNSGpilI0Kc5f4KKGCpRDuELuuSQlsHvvMidQrd1 -KCdtGx5HDYIx8+wFuENWLvCTn/wgPAkFn+jiOXooBbc8ZYRSSaynfg1mwKiGhOCq -+HVWxsuSPK1RggkM1a02jL6Wo/poIlvLoDSa66C4rhFvfdfVJTIef6ePFoy5cJMs -8fFDMORgFxOoqlybXdrFblPA4W6T28KGEpJg2YYCndwbF73CzvE+oke3nxS7/jKx -TxHVISMncVN63rnrhKXMdKBS6oGQ+FHWcFT4Xkm0hSgkUDUNvH2LshU1DIy4akNi -+4aVQ1tyRwhnF7+5YTL6gE7+zkYMsNvE6l9E9MLanSyE9nxOH4J8w4UAnU1vdviC -pB+W5xluZos6c2u0mY4wE/veWWIWDWWt1eOruFPXPg== ------END CERTIFICATE----- diff --git a/tests/harbor_ca.key b/tests/harbor_ca.key deleted file mode 100644 index 7bd9339..0000000 --- a/tests/harbor_ca.key +++ /dev/null @@ -1,52 +0,0 @@ ------BEGIN PRIVATE KEY----- -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 -TCzHlmv6jAQjcDqW7qCr4HtEMrA62FY= ------END PRIVATE KEY----- diff --git a/tests/hostcfg.sh b/tests/hostcfg.sh deleted file mode 100755 index 22ccaca..0000000 --- a/tests/hostcfg.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash -IP=$(hostname -I | awk '{print $1}') - -#echo $IP -sudo sed "s/reg.mydomain.com/$IP/" make/harbor.yml.tmpl |sudo tee make/harbor.yml - -# enable internal tls -echo "internal_tls:" >> make/harbor.yml -echo " enabled: true" >> make/harbor.yml -echo " dir: /etc/harbor/tls/internal" >> make/harbor.yml - -# TODO: remove it when scanner adapter support internal access of harbor -echo "storage_service:" >> make/harbor.yml -echo " ca_bundle: /data/cert/server.crt" >> make/harbor.yml - -sed "s|/your/certificate/path|/data/cert/server.crt|g" -i make/harbor.yml -sed "s|/your/private/key/path|/data/cert/server.key|g" -i make/harbor.yml diff --git a/tests/integration.sh b/tests/integration.sh deleted file mode 100755 index decdec0..0000000 --- a/tests/integration.sh +++ /dev/null @@ -1,224 +0,0 @@ -#!/bin/bash -# Copyright Project Harbor Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -set -x -gsutil version -l -set +x - -docker-compose version - -## -------------------------------------------- Pre-condition -------------------------------------------- -if [[ $DRONE_REPO != "goharbor/harbor" ]]; then - echo "Only run tests again Harbor Repo." - exit 1 -fi -# It won't package an new harbor build against tag, just pick up a build which passed CI and push to release. -if [[ $DRONE_BUILD_EVENT == "tag" || $DRONE_BUILD_EVENT == "pull_request" ]]; then - echo "We do nothing against 'tag' and 'pull request'." - exit 0 -fi - -## --------------------------------------------- Init Env ------------------------------------------------- -dpkg -l > package.list -# Start Xvfb for Chrome headlesss -Xvfb -ac :99 -screen 0 1280x1024x16 & export DISPLAY=:99 - -export DRONE_SERVER=$DRONE_SERVER -export DRONE_TOKEN=$DRONE_TOKEN - -upload_build=false -nightly_run=false -upload_latest_build=false -upload_bundle_success=false -latest_build_file='latest.build' -publish_npm=true - -harbor_offline_build_bundle="" -harbor_online_build_bundle="" -harbor_logs_bucket="harbor-ci-logs" -harbor_builds_bucket="harbor-builds" -harbor_releases_bucket="harbor-releases" -harbor_ci_pipeline_store_bucket="harbor-ci-pipeline-store/latest" -harbor_target_bucket="" -if [[ $DRONE_BRANCH == "master" ]]; then - harbor_target_bucket=$harbor_builds_bucket -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 - -## --------------------------------------------- Init Version ----------------------------------------------- -buildinfo=$(drone build info goharbor/harbor $DRONE_BUILD_NUMBER) -echo $buildinfo -# the target release version is the version of next release(RC or GA). It needs to be updated on creating new release branch. -target_release_version=$(cat ./VERSION) -# the harbor package version is for both online and offline installer. -# harbor-offline-installer-v1.5.2-build.8.tgz -Harbor_Package_Version=$target_release_version-'build.'$DRONE_BUILD_NUMBER -# the harbor assets version is for tag of harbor images: -# 1, On master branch, it's same as package version. -# 2, On release branch(others), it would set to the target realese version so that we can rename the latest passed CI build to publish. -if [[ $DRONE_BRANCH == "master" ]]; then - Harbor_Assets_Version=$Harbor_Package_Version -else - Harbor_Assets_Version=$target_release_version -fi -export Harbor_Assets_Version=$Harbor_Assets_Version -# the env is for online and offline package. -export Harbor_Package_Version=$Harbor_Package_Version -export NPM_REGISTRY=$NPM_REGISTRY -# release branch must have their own base image with branch name, master and others will use the dev as base. -if [[ $DRONE_BRANCH == "release-"* ]]; then - Harbor_Build_Base_Tag=$target_release_version -else - Harbor_Build_Base_Tag=dev -fi -export Harbor_Build_Base_Tag=$Harbor_Build_Base_Tag - -echo "--------------------------------------------------" -echo "Harbor Package version: $Harbor_Package_Version" -echo "Harbor Assets version: $Harbor_Assets_Version" -echo "Harbor Build Base tag: $Harbor_Build_Base_Tag" -echo "--------------------------------------------------" - -# GS util -function uploader { - gsutil cp $1 gs://$2/$1 - gsutil -D setacl public-read gs://$2/$1 &> /dev/null -} - -function package_installer { - echo "Package Harbor offline installer." - robot --removekeywords TAG:secret --include Bundle tests/robot-cases/Group0-Distro-Harbor - harbor_offline_build_bundle=$(basename harbor-offline-installer-*.tgz) - harbor_online_build_bundle=$(basename harbor-online-installer-*.tgz) - upload_build=true - echo "Package name is: $harbor_offline_build_bundle" - du -ks $harbor_offline_build_bundle | awk '{print $1 / 1024}' | { read x; echo $x MB; } -} - -# publish images to Docker Hub -function publishImage { - echo "Publishing images to Docker Hub..." - echo "The images on the host:" - # for master, will use 'dev' as the tag name - # for release-*, will use 'release-*-dev' as the tag name, like release-v1.8.0-dev - if [[ $DRONE_BRANCH == "master" ]]; then - image_tag=dev - fi - if [[ $DRONE_BRANCH == "release-"* ]]; then - image_tag=$Harbor_Assets_Version-dev - fi - # rename the images with tag "dev" and push to Docker Hub - docker images - docker login -u $DOCKER_HUB_USERNAME -p $DOCKER_HUB_PASSWORD - docker images | grep goharbor | grep -v "\-base" | sed -n "s|\(goharbor/[-._a-z0-9]*\)\s*\(.*$Harbor_Assets_Version\).*|docker tag \1:\2 \1:$image_tag;docker push \1:$image_tag|p" | bash - echo "Images are published successfully" - docker images -} - -echo "--------------------------------------------------" -echo "Running CI for $DRONE_BUILD_EVENT on $DRONE_BRANCH" -echo "--------------------------------------------------" - -## -# Any merge code(PUSH) on branch master, release-* will trigger package offline installer. -# -# Put code here is because that it needs clean code to build installer. -## -if [[ $DRONE_BRANCH == "master" || $DRONE_BRANCH == *"refs/tags"* || $DRONE_BRANCH == "release-"* ]]; then - if [[ $DRONE_BUILD_EVENT == "push" ]]; then - package_installer - upload_latest_build=true - echo -en "$HARBOR_SIGN_KEY" | gpg --import - gpg -v -ab -u $HARBOR_SIGN_KEY_ID $harbor_offline_build_bundle - gpg -v -ab -u $HARBOR_SIGN_KEY_ID $harbor_online_build_bundle - fi -fi - -## --------------------------------------------- Upload Harbor Bundle File --------------------------------------- -# -# Build storage structure: -# -# 1(master), harbor-builds/harbor-offline-installer-*.tgz -# latest.build -# harbor-offline-installer-latest.tgz - -# 2(others), harbor-releases/${branch}/harbor-offline-installer-*.tgz -# latest.build -# harbor-offline-installer-latest.tgz -# -set -e -if [ $upload_build == true ]; then - cp ${harbor_offline_build_bundle} harbor-offline-installer-latest.tgz - cp ${harbor_offline_build_bundle}.asc harbor-offline-installer-latest.tgz.asc - uploader ${harbor_offline_build_bundle} $harbor_target_bucket - uploader ${harbor_offline_build_bundle}.asc $harbor_target_bucket - uploader ${harbor_online_build_bundle} $harbor_target_bucket - uploader ${harbor_online_build_bundle}.asc $harbor_target_bucket - uploader harbor-offline-installer-latest.tgz $harbor_target_bucket - uploader harbor-offline-installer-latest.tgz.asc $harbor_target_bucket - upload_bundle_success=true -fi - - -## --------------------------------------------- Upload Harbor Dev Images --------------------------------------- -# -# Any merge code(PUSH) on branch master, release-* will trigger push dev images. -# -## -if [[ $DRONE_BRANCH == "master" || $DRONE_BRANCH == "release-"* ]]; then - if [[ $DRONE_BUILD_EVENT == "push" ]]; then - publishImage - fi -fi - -## --------------------------------------------- Upload Harbor Latest Build File ---------------------------------- -# -# latest.build file holds the latest offline installer url, it must be sure that the installer has been uploaded successfull. -# -if [ $upload_latest_build == true ] && [ $upload_bundle_success == true ]; then - echo 'https://storage.googleapis.com/'$harbor_target_bucket/$harbor_offline_build_bundle > $latest_build_file - uploader $latest_build_file $harbor_target_bucket -fi - -## --------------------------------------------- Upload securego results ------------------------------------------ -#if [ $DRONE_BUILD_EVENT == "push" ]; then -# go get github.com/securego/gosec/cmd/gosec -# go get github.com/dghubble/sling -# make gosec -e GOSECRESULTS=harbor-gosec-results-latest.json -# echo $git_commit > ./harbor-gosec-results-latest-version -# uploader harbor-gosec-results-latest.json $harbor_target_bucket -# uploader harbor-gosec-results-latest-version $harbor_target_bucket -#fi - -## ------------------------------------------------ Tear Down ----------------------------------------------------- -if [ -f "$keyfile" ]; then - rm -f $keyfile -fi - diff --git a/tests/ldap_test.ldif b/tests/ldap_test.ldif deleted file mode 100644 index 790d436..0000000 --- a/tests/ldap_test.ldif +++ /dev/null @@ -1,792 +0,0 @@ -# User entry doesn't belong to harbor_users, it should fail to login -dn: uid=test,dc=example,dc=com -uid: test -cn: test -sn: 3 -objectClass: top -objectClass: posixAccount -objectClass: inetOrgPerson -loginShell: /bin/bash -homeDirectory: /home/test -uidNumber: 1001 -gidNumber: 1001 -userPassword: 123456 -mail: test@example.com -gecos: test - -# OU for People -dn: ou=people,dc=example,dc=com -objectClass: organizationalUnit -ou: People - -# OU for Groups -dn: ou=groups,dc=example,dc=com -objectClass: organizationalUnit -ou: Groups - -# Group Entry harbor_users -dn: cn=harbor_users,ou=groups,dc=example,dc=com -cn: harbor_users -description: All users -member: cn=mike,ou=people,dc=example,dc=com -member: cn=mike02,ou=people,dc=example,dc=com -member: cn=mike03,ou=people,dc=example,dc=com -member: cn=mike04,ou=people,dc=example,dc=com -member: cn=mike05,ou=people,dc=example,dc=com -objectclass: groupOfNames -objectclass: top - -# Group Entry harbor_group -dn: cn=harbor_group,ou=groups,dc=example,dc=com -cn: harbor_group -description: harbor group -o: hgroup -member: cn=mike,ou=people,dc=example,dc=com -member: cn=mike02,ou=people,dc=example,dc=com -objectclass: groupOfNames -objectclass: top - -# Group Entry harbor_group2 -dn: cn=harbor_group2,ou=groups,dc=example,dc=com -cn: harbor_group2 -description: harbor group2 -member: cn=mike,ou=people,dc=example,dc=com -member: cn=mike02,ou=people,dc=example,dc=com -objectclass: groupOfNames -objectclass: top - -# Group Entry harbor_group3 -dn: cn=harbor_group3,ou=groups,dc=example,dc=com -cn: harbor_group3 -description: harbor group3 -member: cn=user001,ou=people,dc=example,dc=com -member: cn=user002,ou=people,dc=example,dc=com -member: cn=user003,ou=people,dc=example,dc=com -member: cn=user004,ou=people,dc=example,dc=com -member: cn=user005,ou=people,dc=example,dc=com -member: cn=user006,ou=people,dc=example,dc=com -member: cn=user007,ou=people,dc=example,dc=com -member: cn=user008,ou=people,dc=example,dc=com -member: cn=user009,ou=people,dc=example,dc=com -member: cn=user010,ou=people,dc=example,dc=com -member: cn=user011,ou=people,dc=example,dc=com -member: cn=user012,ou=people,dc=example,dc=com -member: cn=user013,ou=people,dc=example,dc=com -member: cn=user014,ou=people,dc=example,dc=com -member: cn=user015,ou=people,dc=example,dc=com -member: cn=user016,ou=people,dc=example,dc=com -member: cn=user017,ou=people,dc=example,dc=com -member: cn=user018,ou=people,dc=example,dc=com -member: cn=user019,ou=people,dc=example,dc=com -member: cn=user020,ou=people,dc=example,dc=com -member: cn=user021,ou=people,dc=example,dc=com -member: cn=user022,ou=people,dc=example,dc=com -member: cn=user023,ou=people,dc=example,dc=com -member: cn=user024,ou=people,dc=example,dc=com -member: cn=user025,ou=people,dc=example,dc=com -member: cn=user026,ou=people,dc=example,dc=com -member: cn=user027,ou=people,dc=example,dc=com -member: cn=user028,ou=people,dc=example,dc=com -objectclass: groupOfNames -objectclass: top - -# Group Entry harbor_guest -dn: cn=harbor_guest,ou=groups,dc=example,dc=com -cn: harbor_guest -description: harbor guest -member: cn=guest_user,ou=people,dc=example,dc=com -objectclass: groupOfNames -objectclass: top - -# Group Entry harbor_dev -dn: cn=harbor_dev,ou=groups,dc=example,dc=com -cn: harbor_dev -description: harbor developers -member: cn=dev_user,ou=people,dc=example,dc=com -objectclass: groupOfNames -objectclass: top - -# Group Entry harbor_admin -dn: cn=harbor_admin,ou=groups,dc=example,dc=com -cn: harbor_admin -description: harbor developers -member: cn=admin_user,ou=people,dc=example,dc=com -objectclass: groupOfNames -objectclass: top - - -# User belongs to harbor_user -dn: cn=mike,ou=people,dc=example,dc=com -cn: mike -gidnumber: 10000 -givenname: mike -homedirectory: /home/mike -loginshell: /bin/bash -mail: mike@example.com -objectclass: top -objectclass: posixAccount -objectclass: shadowAccount -objectclass: inetOrgPerson -objectclass: organizationalPerson -objectclass: person -sn: Joe -uid: mike -uidnumber: 5000 -userpassword: {MD5}wb68DeX0CyENafzUADNn9A== -memberof: cn=harbor_users,ou=groups,dc=example,dc=com - -# User entry to add project member testcase -dn: cn=mike02,ou=people,dc=example,dc=com -cn: mike02 -gidnumber: 10000 -givenname: mike02 -homedirectory: /home/mike02 -loginshell: /bin/bash -mail: mike02@example.com -objectclass: top -objectclass: posixAccount -objectclass: shadowAccount -objectclass: inetOrgPerson -objectclass: organizationalPerson -objectclass: person -sn: Mike02 -uid: mike02 -uidnumber: 5001 -userpassword: {MD5}wb68DeX0CyENafzUADNn9A== -memberof: cn=harbor_users,ou=groups,dc=example,dc=com - -dn: cn=mike03,ou=people,dc=example,dc=com -cn: mike03 -gidnumber: 10000 -givenname: mike03 -homedirectory: /home/mike03 -loginshell: /bin/bash -mail: mike03@example.com -objectclass: top -objectclass: posixAccount -objectclass: shadowAccount -objectclass: inetOrgPerson -objectclass: organizationalPerson -objectclass: person -sn: Mike03 -uid: mike03 -uidnumber: 5002 -userpassword: {MD5}wb68DeX0CyENafzUADNn9A== -memberof: cn=harbor_users,ou=groups,dc=example,dc=com - -dn: cn=mike04,ou=people,dc=example,dc=com -cn: mike04 -gidnumber: 10000 -givenname: mike04 -homedirectory: /home/mike04 -loginshell: /bin/bash -mail: mike04@example.com -objectclass: top -objectclass: posixAccount -objectclass: shadowAccount -objectclass: inetOrgPerson -objectclass: organizationalPerson -objectclass: person -sn: Mike04 -uid: mike04 -uidnumber: 5003 -userpassword: {MD5}wb68DeX0CyENafzUADNn9A== -memberof: cn=harbor_users,ou=groups,dc=example,dc=com - -dn: cn=mike05,ou=people,dc=example,dc=com -cn: mike05 -gidnumber: 10000 -givenname: mike05 -homedirectory: /home/mike05 -loginshell: /bin/bash -mail: mike05@example.com -objectclass: top -objectclass: posixAccount -objectclass: shadowAccount -objectclass: inetOrgPerson -objectclass: organizationalPerson -objectclass: person -sn: Mike05 -uid: mike05 -uidnumber: 5004 -userpassword: {MD5}wb68DeX0CyENafzUADNn9A== -memberof: cn=harbor_users,ou=groups,dc=example,dc=com - -#user entry for harbor group3 -dn: cn=user001,ou=people,dc=example,dc=com -cn: user001 -gidnumber: 10000 -givenname: user001 -homedirectory: /home/user001 -loginshell: /bin/bash -mail: user001@example.com -objectclass: top -objectclass: posixAccount -objectclass: shadowAccount -objectclass: inetOrgPerson -objectclass: organizationalPerson -objectclass: person -sn: user001 -uid: user001 -uidnumber: 5005 -userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ== - -dn: cn=user002,ou=people,dc=example,dc=com -cn: user002 -gidnumber: 10000 -givenname: user002 -homedirectory: /home/user002 -loginshell: /bin/bash -mail: user002@example.com -objectclass: top -objectclass: posixAccount -objectclass: shadowAccount -objectclass: inetOrgPerson -objectclass: organizationalPerson -objectclass: person -sn: user002 -uid: user002 -uidnumber: 5006 -userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ== - -dn: cn=user003,ou=people,dc=example,dc=com -cn: user003 -gidnumber: 10000 -givenname: user003 -homedirectory: /home/user003 -loginshell: /bin/bash -mail: user003@example.com -objectclass: top -objectclass: posixAccount -objectclass: shadowAccount -objectclass: inetOrgPerson -objectclass: organizationalPerson -objectclass: person -sn: user003 -uid: user003 -uidnumber: 5007 -userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ== - -dn: cn=user004,ou=people,dc=example,dc=com -cn: user004 -gidnumber: 10000 -givenname: user004 -homedirectory: /home/user004 -loginshell: /bin/bash -mail: user004@example.com -objectclass: top -objectclass: posixAccount -objectclass: shadowAccount -objectclass: inetOrgPerson -objectclass: organizationalPerson -objectclass: person -sn: user004 -uid: user004 -uidnumber: 5008 -userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ== - -dn: cn=user005,ou=people,dc=example,dc=com -cn: user005 -gidnumber: 10000 -givenname: user005 -homedirectory: /home/user005 -loginshell: /bin/bash -mail: user005@example.com -objectclass: top -objectclass: posixAccount -objectclass: shadowAccount -objectclass: inetOrgPerson -objectclass: organizationalPerson -objectclass: person -sn: user005 -uid: user005 -uidnumber: 5009 -userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ== - -dn: cn=user006,ou=people,dc=example,dc=com -cn: user006 -gidnumber: 10000 -givenname: user006 -homedirectory: /home/user006 -loginshell: /bin/bash -mail: user006@example.com -objectclass: top -objectclass: posixAccount -objectclass: shadowAccount -objectclass: inetOrgPerson -objectclass: organizationalPerson -objectclass: person -sn: user006 -uid: user006 -uidnumber: 5010 -userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ== - -dn: cn=user007,ou=people,dc=example,dc=com -cn: user007 -gidnumber: 10000 -givenname: user007 -homedirectory: /home/user007 -loginshell: /bin/bash -mail: user007@example.com -objectclass: top -objectclass: posixAccount -objectclass: shadowAccount -objectclass: inetOrgPerson -objectclass: organizationalPerson -objectclass: person -sn: user007 -uid: user007 -uidnumber: 5011 -userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ== - -dn: cn=user008,ou=people,dc=example,dc=com -cn: user008 -gidnumber: 10000 -givenname: user008 -homedirectory: /home/user008 -loginshell: /bin/bash -mail: user008@example.com -objectclass: top -objectclass: posixAccount -objectclass: shadowAccount -objectclass: inetOrgPerson -objectclass: organizationalPerson -objectclass: person -sn: user008 -uid: user008 -uidnumber: 5012 -userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ== - -dn: cn=user009,ou=people,dc=example,dc=com -cn: user009 -gidnumber: 10000 -givenname: user009 -homedirectory: /home/user009 -loginshell: /bin/bash -mail: user009@example.com -objectclass: top -objectclass: posixAccount -objectclass: shadowAccount -objectclass: inetOrgPerson -objectclass: organizationalPerson -objectclass: person -sn: user009 -uid: user009 -uidnumber: 5013 -userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ== - -dn: cn=user010,ou=people,dc=example,dc=com -cn: user010 -gidnumber: 10000 -givenname: user010 -homedirectory: /home/user010 -loginshell: /bin/bash -mail: user010@example.com -objectclass: top -objectclass: posixAccount -objectclass: shadowAccount -objectclass: inetOrgPerson -objectclass: organizationalPerson -objectclass: person -sn: user010 -uid: user010 -uidnumber: 5014 -userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ== - -dn: cn=user011,ou=people,dc=example,dc=com -cn: user011 -gidnumber: 10000 -givenname: user011 -homedirectory: /home/user011 -loginshell: /bin/bash -mail: user011@example.com -objectclass: top -objectclass: posixAccount -objectclass: shadowAccount -objectclass: inetOrgPerson -objectclass: organizationalPerson -objectclass: person -sn: user011 -uid: user011 -uidnumber: 5015 -userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ== - -dn: cn=user012,ou=people,dc=example,dc=com -cn: user012 -gidnumber: 10000 -givenname: user012 -homedirectory: /home/user012 -loginshell: /bin/bash -mail: user012@example.com -objectclass: top -objectclass: posixAccount -objectclass: shadowAccount -objectclass: inetOrgPerson -objectclass: organizationalPerson -objectclass: person -sn: user012 -uid: user012 -uidnumber: 5016 -userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ== - -dn: cn=user013,ou=people,dc=example,dc=com -cn: user013 -gidnumber: 10000 -givenname: user013 -homedirectory: /home/user013 -loginshell: /bin/bash -mail: user013@example.com -objectclass: top -objectclass: posixAccount -objectclass: shadowAccount -objectclass: inetOrgPerson -objectclass: organizationalPerson -objectclass: person -sn: user013 -uid: user013 -uidnumber: 5017 -userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ== - -dn: cn=user014,ou=people,dc=example,dc=com -cn: user014 -gidnumber: 10000 -givenname: user014 -homedirectory: /home/user014 -loginshell: /bin/bash -mail: user014@example.com -objectclass: top -objectclass: posixAccount -objectclass: shadowAccount -objectclass: inetOrgPerson -objectclass: organizationalPerson -objectclass: person -sn: user014 -uid: user014 -uidnumber: 5018 -userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ== - -dn: cn=user015,ou=people,dc=example,dc=com -cn: user015 -gidnumber: 10000 -givenname: user015 -homedirectory: /home/user015 -loginshell: /bin/bash -mail: user015@example.com -objectclass: top -objectclass: posixAccount -objectclass: shadowAccount -objectclass: inetOrgPerson -objectclass: organizationalPerson -objectclass: person -sn: user015 -uid: user015 -uidnumber: 5019 -userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ== - -dn: cn=user016,ou=people,dc=example,dc=com -cn: user016 -gidnumber: 10000 -givenname: user016 -homedirectory: /home/user016 -loginshell: /bin/bash -mail: user016@example.com -objectclass: top -objectclass: posixAccount -objectclass: shadowAccount -objectclass: inetOrgPerson -objectclass: organizationalPerson -objectclass: person -sn: user016 -uid: user016 -uidnumber: 5020 -userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ== - -dn: cn=user017,ou=people,dc=example,dc=com -cn: user017 -gidnumber: 10000 -givenname: user017 -homedirectory: /home/user017 -loginshell: /bin/bash -mail: user017@example.com -objectclass: top -objectclass: posixAccount -objectclass: shadowAccount -objectclass: inetOrgPerson -objectclass: organizationalPerson -objectclass: person -sn: user017 -uid: user017 -uidnumber: 5021 -userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ== - -dn: cn=user018,ou=people,dc=example,dc=com -cn: user018 -gidnumber: 10000 -givenname: user018 -homedirectory: /home/user018 -loginshell: /bin/bash -mail: user018@example.com -objectclass: top -objectclass: posixAccount -objectclass: shadowAccount -objectclass: inetOrgPerson -objectclass: organizationalPerson -objectclass: person -sn: user018 -uid: user018 -uidnumber: 5022 -userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ== - -dn: cn=user019,ou=people,dc=example,dc=com -cn: user019 -gidnumber: 10000 -givenname: user019 -homedirectory: /home/user019 -loginshell: /bin/bash -mail: user019@example.com -objectclass: top -objectclass: posixAccount -objectclass: shadowAccount -objectclass: inetOrgPerson -objectclass: organizationalPerson -objectclass: person -sn: user019 -uid: user019 -uidnumber: 5023 -userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ== - -dn: cn=user020,ou=people,dc=example,dc=com -cn: user020 -gidnumber: 10000 -givenname: user020 -homedirectory: /home/user020 -loginshell: /bin/bash -mail: user020@example.com -objectclass: top -objectclass: posixAccount -objectclass: shadowAccount -objectclass: inetOrgPerson -objectclass: organizationalPerson -objectclass: person -sn: user020 -uid: user020 -uidnumber: 5024 -userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ== - -dn: cn=user021,ou=people,dc=example,dc=com -cn: user021 -gidnumber: 10000 -givenname: user021 -homedirectory: /home/user021 -loginshell: /bin/bash -mail: user021@example.com -objectclass: top -objectclass: posixAccount -objectclass: shadowAccount -objectclass: inetOrgPerson -objectclass: organizationalPerson -objectclass: person -sn: user021 -uid: user021 -uidnumber: 5025 -userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ== - -dn: cn=user022,ou=people,dc=example,dc=com -cn: user022 -gidnumber: 10000 -givenname: user022 -homedirectory: /home/user022 -loginshell: /bin/bash -mail: user022@example.com -objectclass: top -objectclass: posixAccount -objectclass: shadowAccount -objectclass: inetOrgPerson -objectclass: organizationalPerson -objectclass: person -sn: user022 -uid: user022 -uidnumber: 5026 -userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ== - -dn: cn=user023,ou=people,dc=example,dc=com -cn: user023 -gidnumber: 10000 -givenname: user023 -homedirectory: /home/user023 -loginshell: /bin/bash -mail: user023@example.com -objectclass: top -objectclass: posixAccount -objectclass: shadowAccount -objectclass: inetOrgPerson -objectclass: organizationalPerson -objectclass: person -sn: user023 -uid: user023 -uidnumber: 5027 -userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ== - -dn: cn=user024,ou=people,dc=example,dc=com -cn: user024 -gidnumber: 10000 -givenname: user024 -homedirectory: /home/user024 -loginshell: /bin/bash -mail: user024@example.com -objectclass: top -objectclass: posixAccount -objectclass: shadowAccount -objectclass: inetOrgPerson -objectclass: organizationalPerson -objectclass: person -sn: user024 -uid: user024 -uidnumber: 5028 -userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ== - -dn: cn=user025,ou=people,dc=example,dc=com -cn: user025 -gidnumber: 10000 -givenname: user025 -homedirectory: /home/user025 -loginshell: /bin/bash -mail: user025@example.com -objectclass: top -objectclass: posixAccount -objectclass: shadowAccount -objectclass: inetOrgPerson -objectclass: organizationalPerson -objectclass: person -sn: user025 -uid: user025 -uidnumber: 5029 -userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ== - -dn: cn=user026,ou=people,dc=example,dc=com -cn: user026 -gidnumber: 10000 -givenname: user026 -homedirectory: /home/user026 -loginshell: /bin/bash -mail: user026@example.com -objectclass: top -objectclass: posixAccount -objectclass: shadowAccount -objectclass: inetOrgPerson -objectclass: organizationalPerson -objectclass: person -sn: user026 -uid: user026 -uidnumber: 5030 -userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ== - -dn: cn=user027,ou=people,dc=example,dc=com -cn: user027 -gidnumber: 10000 -givenname: user027 -homedirectory: /home/user027 -loginshell: /bin/bash -mail: user027@example.com -objectclass: top -objectclass: posixAccount -objectclass: shadowAccount -objectclass: inetOrgPerson -objectclass: organizationalPerson -objectclass: person -sn: user027 -uid: user027 -uidnumber: 5031 -userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ== - -dn: cn=user028,ou=people,dc=example,dc=com -cn: user028 -gidnumber: 10000 -givenname: user028 -homedirectory: /home/user028 -loginshell: /bin/bash -mail: user028@example.com -objectclass: top -objectclass: posixAccount -objectclass: shadowAccount -objectclass: inetOrgPerson -objectclass: organizationalPerson -objectclass: person -sn: user028 -uid: user028 -uidnumber: 5032 -userpassword: {MD5}jMx5MaPXabPyX7F0SoFxYQ== - -dn: cn=guest_user,ou=people,dc=example,dc=com -cn: guest_user -gidnumber: 10000 -givenname: guest_user -homedirectory: /home/guest_user -loginshell: /bin/bash -mail: guest_user@example.com -objectclass: top -objectclass: posixAccount -objectclass: shadowAccount -objectclass: inetOrgPerson -objectclass: organizationalPerson -objectclass: person -sn: guest_user -uid: guest_user -uidnumber: 6001 -userpassword: {MD5}wb68DeX0CyENafzUADNn9A== -memberof: cn=harbor_guest,ou=groups,dc=example,dc=com - -dn: cn=dev_user,ou=people,dc=example,dc=com -cn: dev_user -gidnumber: 10000 -givenname: guest_user -homedirectory: /home/dev_user -loginshell: /bin/bash -mail: dev_user@example.com -objectclass: top -objectclass: posixAccount -objectclass: shadowAccount -objectclass: inetOrgPerson -objectclass: organizationalPerson -objectclass: person -sn: dev_user -uid: dev_user -uidnumber: 6002 -userpassword: {MD5}wb68DeX0CyENafzUADNn9A== -memberof: cn=harbor_dev,ou=groups,dc=example,dc=com - -dn: cn=admin_user,ou=people,dc=example,dc=com -cn: admin_user -gidnumber: 10000 -givenname: admin_user -homedirectory: /home/admin_user -loginshell: /bin/bash -mail: admin_user@example.com -objectclass: top -objectclass: posixAccount -objectclass: shadowAccount -objectclass: inetOrgPerson -objectclass: organizationalPerson -objectclass: person -sn: admin_user -uid: admin_user -uidnumber: 6003 -userpassword: {MD5}wb68DeX0CyENafzUADNn9A== -memberof: cn=harbor_admin,ou=groups,dc=example,dc=com -memberof: cn=harbor_root,dc=harbor,dc=example,dc=com - - -dn: dc=harbor,dc=example,dc=com -associateddomain: harbor -dc: harbor -objectclass: dNSDomain -objectclass: domainRelatedObject -objectclass: top - -# Group Entry harbor_admin -dn: cn=harbor_root,dc=harbor,dc=example,dc=com -cn: harbor_root -description: harbor root users -member: cn=admin_user,ou=people,dc=example,dc=com -objectclass: groupOfNames -objectclass: top \ No newline at end of file diff --git a/tests/ldapprepare.sh b/tests/ldapprepare.sh deleted file mode 100755 index 3bc22a1..0000000 --- a/tests/ldapprepare.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash -NAME=ldap_server -docker rm -f $NAME 2>/dev/null - -docker run --env LDAP_ORGANISATION="Harbor." \ ---env LDAP_DOMAIN="example.com" \ ---env LDAP_ADMIN_PASSWORD="admin" \ ---env LDAP_TLS_VERIFY_CLIENT="never" \ --p 389:389 \ --p 636:636 \ ---detach --name $NAME osixia/openldap:1.1.7 - -sleep 5 -docker cp ldap_test.ldif ldap_server:/ -docker exec ldap_server ldapadd -x -D "cn=admin,dc=example,dc=com" -w admin -f /ldap_test.ldif -ZZ - -# failed and retry -for number in {1..10} -do - if [ ! $? -eq 0 ]; then - sleep 6 - echo "retry in $number " - docker exec ldap_server ldapadd -x -D "cn=admin,dc=example,dc=com" -w admin -f /ldap_test.ldif -ZZ - else - exit 0 - fi -done -exit 1 \ No newline at end of file diff --git a/tests/notarytest.sh b/tests/notarytest.sh deleted file mode 100755 index 4cdd515..0000000 --- a/tests/notarytest.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh - -set -e - -TIMEOUT=10 -while [ $TIMEOUT -gt 0 ]; do - STATUS=$(curl -s -o /dev/null -w '%{http_code}' https://127.0.0.1:4443/v2/ -kv) - if [ $STATUS -eq 401 ]; then - echo "Notary is running success." - break - fi - TIMEOUT=$(($TIMEOUT - 1)) - sleep 5 -done - -if [ $TIMEOUT -eq 0 ]; then - echo "Notary is running fail." - exit 1 -fi diff --git a/tests/private_key.pem b/tests/private_key.pem deleted file mode 100644 index d2dc85d..0000000 --- a/tests/private_key.pem +++ /dev/null @@ -1,51 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -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 ------END RSA PRIVATE KEY----- diff --git a/tests/pushimage.sh b/tests/pushimage.sh deleted file mode 100755 index dd5f4ea..0000000 --- a/tests/pushimage.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash -set -x -set -e - -IP=$(hostname -I | awk '{print $1}') -docker pull hello-world -docker pull busybox -docker login -u admin -p Harbor12345 $IP:5000 - -docker tag hello-world $IP:5000/library/hello-world:latest -docker push $IP:5000/library/hello-world:latest -echo "$? pushed hello world" - -docker tag busybox $IP:5000/library/busybox:latest -docker push $IP:5000/library/busybox:latest -echo "$? pushed busybox" diff --git a/tests/reg_config.yml b/tests/reg_config.yml deleted file mode 100644 index db6d2bc..0000000 --- a/tests/reg_config.yml +++ /dev/null @@ -1,18 +0,0 @@ -version: 0.1 -log: - fields: - service: registry -storage: - cache: - blobdescriptor: inmemory - filesystem: - rootdirectory: /storage -http: - addr: :5000 - headers: - X-Content-Type-Options: [nosniff] -health: - storagedriver: - enabled: true - interval: 10s - threshold: 3 diff --git a/tests/showtime.sh b/tests/showtime.sh deleted file mode 100755 index b77cf09..0000000 --- a/tests/showtime.sh +++ /dev/null @@ -1,13 +0,0 @@ -#/bin/env bash - -if [ ! -z "$*" ]; then - $@ 2>&1 | while read line;do - echo $(date +"%T") $line - done - exit ${PIPESTATUS[0]} -else - while read line;do - echo $(date +"%T") $line - done - echo ret $? -fi \ No newline at end of file diff --git a/tests/startuptest.sh b/tests/startuptest.sh deleted file mode 100755 index 7a41cd7..0000000 --- a/tests/startuptest.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/sh - -set +e - -TIMEOUT=12 -while [ $TIMEOUT -gt 0 ]; do - STATUS=$(curl --insecure -s -o /dev/null -w '%{http_code}' https://localhost/) - if [ $STATUS -eq 200 ]; then - break - fi - TIMEOUT=$(($TIMEOUT - 1)) - sleep 5 -done - -if [ $TIMEOUT -eq 0 ]; then - echo "Harbor cannot reach within one minute." - exit 1 -fi - -curl --insecure -s -L -H "Accept: application/json" https://localhost/ | grep "Harbor" > /dev/null -if [ $? -eq 0 ]; then - echo "Harbor is running success." -else - echo "Harbor is running fail." - exit 1 -fi - - diff --git a/tests/swaggerchecker.sh b/tests/swaggerchecker.sh deleted file mode 100755 index ecb70ef..0000000 --- a/tests/swaggerchecker.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/sh - -set +e - -SWAGGER_ONLINE_VALIDATOR="http://online.swagger.io/validator" -if [ $TRAVIS_EVENT_TYPE = "push" ]; then - HARBOR_SWAGGER_FILE="https://raw.githubusercontent.com/$TRAVIS_REPO_SLUG/$TRAVIS_COMMIT/api/harbor/swagger.yaml" -elif [ $TRAVIS_EVENT_TYPE = "pull_request" ]; then - HARBOR_SWAGGER_FILE="https://raw.githubusercontent.com/$TRAVIS_PULL_REQUEST_SLUG/$TRAVIS_PULL_REQUEST_SHA/api/harbor/swagger.yaml" -else - echo "* don't support this kinds of action ($TRAVIS_EVENT_TYPE), but don't fail the travis CI." - exit 0 -fi -HARBOR_SWAGGER_VALIDATOR_URL="$SWAGGER_ONLINE_VALIDATOR/debug?url=$HARBOR_SWAGGER_FILE" -echo $HARBOR_SWAGGER_VALIDATOR_URL - -# Now try to ping swagger online validator, then to use it to do the validation. -eval curl -f -I $SWAGGER_ONLINE_VALIDATOR -curl_ping_res=$? -if [ ${curl_ping_res} -eq 0 ]; then - echo "* cURL ping swagger validator returned success" -else - echo "* cURL ping swagger validator returned an error (${curl_ping_res}), but don't fail the travis CI here." - exit 0 -fi - -# Use the swagger online validator to validate the harbor swagger file. -eval curl -s $HARBOR_SWAGGER_VALIDATOR_URL > output.json -curl_validate_res=$? -validate_expected_results="{}" -validate_actual_results=$(cat < output.json) - -if [ ${curl_validate_res} -eq 0 ]; then - if [ $validate_actual_results = $validate_expected_results ]; then - echo "* cURL check Harbor swagger file returned success" - else - echo "* cURL check Harbor swagger file returned an error ($validate_actual_results)" - fi -else - echo "* cURL check Harbor swagger file returned an error (${curl_validate_res})" - exit ${curl_validate_res} -fi diff --git a/tests/testprepare.sh b/tests/testprepare.sh deleted file mode 100755 index a44af76..0000000 --- a/tests/testprepare.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash -set -e -cp tests/docker-compose.test.yml make/. - -mkdir -p core -cp /data/secret/core/private_key.pem /etc/core/ - -mkdir src/core/conf -cp make/common/config/core/app.conf src/core/conf/ -if [ "$(uname)" == "Darwin" ]; then - IP=`ifconfig en0 | grep "inet " | grep -Fv 127.0.0.1 | awk '{print $2}'` -else - IP=`ip addr s eth0 |grep "inet "|awk '{print $2}' |awk -F "/" '{print $1}'` -fi -echo "server ip is "$IP - -echo "Current path is" -pwd -cat make/common/config/core/env - -chmod 777 /data/ diff --git a/tests/userlogintest.sh b/tests/userlogintest.sh deleted file mode 100755 index b81b253..0000000 --- a/tests/userlogintest.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh - -set +e - -STATUS_LOGIN=$(curl --insecure -w '%{http_code}' -d "principal=$1&password=$2" https://localhost/c/login) -if [ $STATUS_LOGIN -eq 200 ]; then - echo "Login Harbor success." -else - echo "Login Harbor fail." - exit 1 -fi - - -STATUS_LOGOUT=$(curl --insecure -s -o /dev/null -w '%{http_code}' https://localhost/c/log_out) -if [ $STATUS_LOGOUT -eq 200 ]; then - echo "Logout Harbor success." -else - echo "Logout Harbor fail." - exit 1 -fi diff --git a/tests/validatecontainers.sh b/tests/validatecontainers.sh deleted file mode 100755 index 49e9a1b..0000000 --- a/tests/validatecontainers.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh -set -e - -if docker ps --filter "status=restarting" | grep 'vmware'; then - echo "container is restaring, fail CI." - exit 1 -fi diff --git a/tools/migrate_chart/Dockerfile b/tools/migrate_chart/Dockerfile deleted file mode 100644 index ef74572..0000000 --- a/tools/migrate_chart/Dockerfile +++ /dev/null @@ -1,32 +0,0 @@ -FROM python:3.8.5-slim - -ENV HELM_EXPERIMENTAL_OCI=1 -ENV REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt - -COPY ./migrate_chart.py ./migrate_chart.sh / - -RUN ARCH= && dpkgArch="$(uname -m)" \ - && case "${dpkgArch}" in \ - x86_64) ARCH='x64'; curl -fsSL -o / https://get.helm.sh/helm-v3.2.4-linux-amd64.tar.gz \ - tar zxvf /helm-v3.2.4-linux-amd64.tar.gz && \ - pip install click==7.1.2 && \ - pip install requests==2.24.0 && \ - chmod +x /migrate_chart.sh ./migrate_chart.py ;; \ - aarch64) ARCH='arm64'; curl -fsSL -o / https://get.helm.sh/helm-v3.2.4-linux-arm64.tar.gz \ - tar zxvf /helm-v3.2.4-linux-arm64.tar.gz && \ - pip install click==7.1.2 && \ - pip install requests==2.24.0 && \ - chmod +x /migrate_chart.sh ./migrate_chart.py ;; \ - ppc64el) ARCH='ppc64le' ;; \ - s390x) ARCH='s390x' ;; \ - arm64) ARCH='arm64'; curl -fsSL -o / https://get.helm.sh/helm-v3.2.4-linux-arm64.tar.gz \ - tar zxvf /helm-v3.2.4-linux-arm64.tar.gz && \ - pip install click==7.1.2 && \ - pip install requests==2.24.0 && \ - chmod +x /migrate_chart.sh ./migrate_chart.py ;; \ - armhf) ARCH='armv7l' ;; \ - i386) ARCH='x86' ;; \ - *) echo "unsupported architecture"; exit 1 ;; \ - esac - -ENTRYPOINT [ "/migrate_chart.py" ] \ No newline at end of file diff --git a/tools/migrate_chart/Readme.md b/tools/migrate_chart/Readme.md deleted file mode 100644 index 827431e..0000000 --- a/tools/migrate_chart/Readme.md +++ /dev/null @@ -1,36 +0,0 @@ -# Chart Migrating Tool - -Harbor supports two different ways to storage the chart data. - - 1. stored in Harbor registry storage directly via OCI API. - 2. stored in Harbor hosted chartmuseum backend via chartmuseam's API - -There is an performance issue in chartmuseam. For example, on my 2 core 8G memory test environment, to get 10000 charts information needs about 10s to return, In 50000 charts situation, It will cause a timeout error. - -After version 2.0, Harbor becomes to the OCI registry. So It can storage chart content directly without chartmuseum. - -This tool used to migrate the legacy helm charts stored in the chartmuseum backend to Harbor OCI registry backend. - -On test environment( 2 core 8G memory), using this tool to migrate 10000 charts needs about 2~3 hours - -## Usages - -Compile the chart with command - -``` sh -docker build -t goharbor/migrate-chart:0.1.0 . -``` - -Migrate charts run command below: - -``` sh -docker run -it --rm -v {{your_chart_data_location}}:/chart_storage -v {{harbor_ca_cert_location}}:/usr/local/share/ca-certificates/harbor_ca.crt goharbor/migrate-chart:0.1.0 --hostname {{harbor_hostname}} --password {{harbor_admin_password}} -``` - -* `your_chart_data_location`: The location of your chart storage chart. By default, it's the `chart_storage` dir inside Harbor's `data_volumn` - -* `harbor_ca_cert_location`: If Harbor enabled HTTPS, you need to add the `ca_cert` for connecting Harbor - -* `harbor_hostname`: The hostname of Harbor - -* `harbor_admin_password`: The password of harbor admin user diff --git a/tools/migrate_chart/migrate_chart.py b/tools/migrate_chart/migrate_chart.py deleted file mode 100644 index 6efb766..0000000 --- a/tools/migrate_chart/migrate_chart.py +++ /dev/null @@ -1,107 +0,0 @@ -#!/usr/local/bin/python3 - -import subprocess -import signal -import sys -from pathlib import Path - -import click -import requests - -MIGRATE_CHART_SCRIPT = '/migrate_chart.sh' -HELM_CMD = '/linux-amd64/helm' -CA_UPDATE_CMD = 'update-ca-certificates' -CHART_URL_PATTERN = "https://{host}/api/v2.0/projects/{project}/repositories/{name}/artifacts/{version}" -CHART_SOURCE_DIR = Path('/chart_storage') - -errs = [] - -def print_exist_errs(): - if errs: - click.echo("Following errors exist", err=True) - for e in errs: - click.echo(e, err=True) - -def graceful_exit(signum, frame): - print_exist_errs() - sys.exit() - -signal.signal(signal.SIGINT, graceful_exit) -signal.signal(signal.SIGTERM, graceful_exit) - -class ChartV2: - - def __init__(self, filepath:Path): - self.filepath = filepath - self.project = self.filepath.parts[-2] - parts = self.filepath.stem.split('-') - flag = False - for i in range(len(parts)-1, -1, -1): - if parts[i][0].isnumeric(): - self.name, self.version = '-'.join(parts[:i]), '-'.join(parts[i:]) - flag = True - break - if not flag: - raise Exception('chart name: {} is illegal'.format('-'.join(parts))) - - def __check_exist(self, hostname, username, password): - return requests.get(CHART_URL_PATTERN.format( - host=hostname, - project=self.project, - name=self.name, - version=self.version), - auth=requests.auth.HTTPBasicAuth(username, password)) - - def migrate(self, hostname, username, password): - res = self.__check_exist(hostname, username, password) - if res.status_code == 200: - raise Exception("Artifact already exist in harbor") - if res.status_code == 401: - raise Exception(res.reason) - - oci_ref = "{host}/{project}/{name}:{version}".format( - host=hostname, - project=self.project, - name=self.name, - version=self.version) - - return subprocess.run([MIGRATE_CHART_SCRIPT, HELM_CMD, self.filepath, oci_ref], - text=True, stdout=subprocess.DEVNULL, stderr=subprocess.PIPE) - - -@click.command() -@click.option('--hostname', default='127.0.0.1', help='the password to login harbor') -@click.option('--username', default='admin', help='The username to login harbor') -@click.option('--password', default='Harbor12345', help='the password to login harbor') -def migrate(hostname, username, password): - """ - Migrate chart v2 to harbor oci registry - """ - if username != 'admin': - raise Exception('This operation only allowed for admin') - subprocess.run([CA_UPDATE_CMD]) - subprocess.run([HELM_CMD, 'registry', 'login', hostname, '--username', username, '--password', password]) - charts = [ChartV2(c) for p in CHART_SOURCE_DIR.iterdir() if p.is_dir() for c in p.iterdir() if c.is_file() and c.name != "index-cache.yaml"] - with click.progressbar(charts, label="Migrating chart ...", length=len(charts), - item_show_func=lambda x: "{}/{}:{} total errors: {}".format(x.project, x.name, x.version, len(errs)) if x else '') as bar: - for chart in bar: - try: - result = chart.migrate(hostname, username, password) - if result.stderr: - errs.append("chart: {name}:{version} in {project} has err: {err}".format( - name=chart.name, - version=chart.version, - project=chart.project, - err=result.stderr - )) - except Exception as e: - errs.append("chart: {name}:{version} in {project} has err: {err}".format( - name=chart.name, - version=chart.version, - project=chart.project, - err=e)) - click.echo("Migration is Done.") - print_exist_errs() - -if __name__ == '__main__': - migrate() diff --git a/tools/migrate_chart/migrate_chart.sh b/tools/migrate_chart/migrate_chart.sh deleted file mode 100644 index a6fd5f7..0000000 --- a/tools/migrate_chart/migrate_chart.sh +++ /dev/null @@ -1,9 +0,0 @@ -#! /bin/bash - -HELM_CMD=$1 -V2_CHART_PATH=$2 -OCI_REF=$3 - -${HELM_CMD} chart save ${V2_CHART_PATH} ${OCI_REF} -${HELM_CMD} chart push ${OCI_REF} -${HELM_CMD} chart remove ${OCI_REF} diff --git a/tools/mockery/Dockerfile b/tools/mockery/Dockerfile deleted file mode 100644 index 468221a..0000000 --- a/tools/mockery/Dockerfile +++ /dev/null @@ -1,33 +0,0 @@ -ARG GOLANG -FROM ${GOLANG} - -ARG MOCKERY_VERSION - -# https://github.com/docker-library/golang/issues/225 -ENV XDG_CACHE_HOME /tmp - -RUN ARCH= && dpkgArch="$(uname -m)" \ - && case "${dpkgArch}" in \ - x86_64) ARCH='x64'; mkdir -p /tmp/mockery-${MOCKERY_VERSION} && \ - curl -fsSL https://github.com/vektra/mockery/releases/download/${MOCKERY_VERSION}/mockery_${MOCKERY_VERSION#v}_Linux_x86_64.tar.gz | tar -xz -C /tmp/mockery-${MOCKERY_VERSION} && \ - mv /tmp/mockery-${MOCKERY_VERSION}/mockery /usr/local/bin && \ - chmod +x /usr/local/bin/mockery && \ - rm -rf /tmp/mockery-${MOCKERY_VERSION} ;; \ - aarch64) ARCH='arm64'; mkdir -p /tmp/mockery-${MOCKERY_VERSION} && \ - curl -fsSL https://github.com/vektra/mockery/releases/download/${MOCKERY_VERSION}/mockery_${MOCKERY_VERSION#v}_Linux_arm64.tar.gz | tar -xz -C /tmp/mockery-${MOCKERY_VERSION} && \ - mv /tmp/mockery-${MOCKERY_VERSION}/mockery /usr/local/bin && \ - chmod +x /usr/local/bin/mockery && \ - rm -rf /tmp/mockery-${MOCKERY_VERSION} ;; \ - ppc64el) ARCH='ppc64le' ;; \ - s390x) ARCH='s390x' ;; \ - arm64) ARCH='arm64'; mkdir -p /tmp/mockery-${MOCKERY_VERSION} && \ - curl -fsSL https://github.com/vektra/mockery/releases/download/${MOCKERY_VERSION}/mockery_${MOCKERY_VERSION#v}_Linux_arm64.tar.gz | tar -xz -C /tmp/mockery-${MOCKERY_VERSION} && \ - mv /tmp/mockery-${MOCKERY_VERSION}/mockery /usr/local/bin && \ - chmod +x /usr/local/bin/mockery && \ - rm -rf /tmp/mockery-${MOCKERY_VERSION} ;; \ - armhf) ARCH='armv7l' ;; \ - i386) ARCH='x86' ;; \ - *) echo "unsupported architecture"; exit 1 ;; \ - esac - -RUN diff --git a/tools/spectral/Dockerfile b/tools/spectral/Dockerfile deleted file mode 100644 index bdb2519..0000000 --- a/tools/spectral/Dockerfile +++ /dev/null @@ -1,19 +0,0 @@ -ARG GOLANG -FROM ${GOLANG} - -ARG SPECTRAL_VERSION - -RUN ARCH= && dpkgArch="$(uname -m)" \ - && case "${dpkgArch}" in \ - x86_64) ARCH='x64'; curl -fsSL -o /usr/bin/spectral https://github.com/stoplightio/spectral/releases/download/$SPECTRAL_VERSION/spectral-linux && chmod +x /usr/bin/spectral ;; \ - aarch64) ARCH='arm64'; ;; \ - ppc64el) ARCH='ppc64le' ;; \ - s390x) ARCH='s390x' ;; \ - arm64) ARCH='arm64'; ;; \ - armhf) ARCH='armv7l' ;; \ - i386) ARCH='x86' ;; \ - *) echo "unsupported architecture"; exit 1 ;; \ - esac - -ENTRYPOINT ["/usr/bin/spectral"] -CMD ["--version"] diff --git a/tools/spectral/functions/requireRequestId.js b/tools/spectral/functions/requireRequestId.js deleted file mode 100644 index f13b60c..0000000 --- a/tools/spectral/functions/requireRequestId.js +++ /dev/null @@ -1,13 +0,0 @@ -module.exports = parameters => { - for (const param of parameters) { - if (param.name === 'X-Request-Id' && param.in === 'header') { - return - } - } - - return [ - { - message: 'X-Request-Id must be in "parameters".', - }, - ]; -}; diff --git a/tools/swagger/Dockerfile b/tools/swagger/Dockerfile deleted file mode 100644 index 36cecb4..0000000 --- a/tools/swagger/Dockerfile +++ /dev/null @@ -1,19 +0,0 @@ -ARG GOLANG -FROM ${GOLANG} - -ARG SWAGGER_VERSION - -RUN ARCH= && dpkgArch="$(uname -m)" \ - && case "${dpkgArch}" in \ - x86_64) ARCH='x64'; curl -fsSL -o /usr/bin/swagger https://github.com/go-swagger/go-swagger/releases/download/$SWAGGER_VERSION/swagger_linux_amd64 && chmod +x /usr/bin/swagger ;; \ - aarch64) ARCH='arm64'; curl -fsSL -o /usr/bin/swagger https://github.com/go-swagger/go-swagger/releases/download/$SWAGGER_VERSION/swagger_linux_arm64 && chmod +x /usr/bin/swagger ;; \ - ppc64el) ARCH='ppc64le' ;; \ - s390x) ARCH='s390x' ;; \ - arm64) ARCH='arm64'; curl -fsSL -o /usr/bin/swagger https://github.com/go-swagger/go-swagger/releases/download/$SWAGGER_VERSION/swagger_linux_amd64 && chmod +x /usr/bin/swagger ;; \ - armhf) ARCH='armv7l' ;; \ - i386) ARCH='x86' ;; \ - *) echo "unsupported architecture"; exit 1 ;; \ - esac - -ENTRYPOINT ["/usr/bin/swagger"] -CMD ["--help"] diff --git a/tools/swagger/templates/README.md b/tools/swagger/templates/README.md deleted file mode 100644 index 9ac7520..0000000 --- a/tools/swagger/templates/README.md +++ /dev/null @@ -1,311 +0,0 @@ -# swagger - -In Stratoscale, we really like the idea of API-first services, and we also really like Go. -We saw the go-swagger library, and thought that most of it can really help us. Generating code from -swagger files is a big problem with a lot of corner cases, and go-swagger is doing great job. - -The one thing that we felt missing, is customization of the server to run with our design principles: - -* Custom `main` function -* Dependency injection -* Limited scopes with unit testing. - -Also: - -* Adding you functions to the generated `configure_swagger_*.go` seems to be a burden. -* Lack of Interface that the service implement. -* Complicated and custom http clients and runtime. - -Those are the changes that this contributor templates are providing: - -## Server - -### The new `restapi` package exposes interfaces - -* Those interfaces can implemented by the developer and are the business logic of the service. -* The implementation of those is extensible. -* The implementation is separated from the generated code. - -### The `restapi` returns an `http.Handler` - -The `restapi.Handler` (see [example](./example/restapi/configure_swagger_petstore.go)) function returns -a standard `http.Handler` - -* Given objects that implements the business logic, we can create a simple http handler. -* This handler is standard go http.Handler, so we can now use any other middleware, library, or framework - that support it. -* This handler is standard, so we understand it better. - -## Client - -* The new client package exposes interfaces, so functions in our code can receive those - interfaces which can be mocked for testing. -* The new client has a config that gets an `*url.URL` to customize the endpoint. -* The new client has a config that gets an `http.RoundTripper` to customize client with libraries, middleware or - frameworks that support the standard library's objects. - -# Example Walk-Through - -In the [example package](https://github.com/Stratoscale/swagger/tree/master/example) you'll find generated code and usage of the pet-store -[swagger file](./example/swagger.yaml). - -* The `restapi`, `models` and `client` are auto-generated by the stratoscale/swagger docker file. -* The `internal` package was manually added and contains the server's business logic. -* The `main.go` file is the entrypoint and contains initializations and dependency injections of the project. - -## Server - -### [restapi](https://github.com/Stratoscale/swagger/tree/master/example/restapi) - -This package is autogenerated and contains the server routing and parameters parsing. - -The modified version contains `restapi.PetAPI` and `restapi.StoreAPI` which were auto generated. - -```go -// PetAPI -type PetAPI interface { - PetCreate(ctx context.Context, params pet.PetCreateParams) middleware.Responder - PetDelete(ctx context.Context, params pet.PetDeleteParams) middleware.Responder - PetGet(ctx context.Context, params pet.PetGetParams) middleware.Responder - PetList(ctx context.Context, params pet.PetListParams) middleware.Responder - PetUpdate(ctx context.Context, params pet.PetUpdateParams) middleware.Responder -} - -//go:generate mockery -name StoreAPI -inpkg - -// StoreAPI -type StoreAPI interface { - InventoryGet(ctx context.Context, params store.InventoryGetParams) middleware.Responder - OrderCreate(ctx context.Context, params store.OrderCreateParams) middleware.Responder - // OrderDelete is For valid response try integer IDs with positive integer value. Negative or non-integer values will generate API errors - OrderDelete(ctx context.Context, params store.OrderDeleteParams) middleware.Responder - // OrderGet is For valid response try integer IDs with value >= 1 and <= 10. Other values will generated exceptions - OrderGet(ctx context.Context, params store.OrderGetParams) middleware.Responder -} -``` - -Each function matches an `operationId` in the swagger file and they are grouped according to -the operation `tags`. - -There is also a `restapi.Config`: - -```go -// Config is configuration for Handler -type Config struct { - PetAPI - StoreAPI - Logger func(string, ...interface{}) - // InnerMiddleware is for the handler executors. These do not apply to the swagger.json document. - // The middleware executes after routing but before authentication, binding and validation - InnerMiddleware func(http.Handler) http.Handler -} -``` - -This config is auto generated and contains all the declared interfaces above. -It is used to initiate an http.Handler with the `Handler` function: - -```go -// Handler returns an http.Handler given the handler configuration -// It mounts all the business logic implementers in the right routing. -func Handler(c Config) (http.Handler, error) { - ... -``` - -Let's look how we use this generated code to build our server. - -### [internal](https://github.com/Stratoscale/swagger/tree/master/example/internal) - -The `internal` package is **not** auto generated and contains the business logic of our server. -We can see two structs that implements the `restapi.PetAPI` and `restapi.StoreAPI` interfaces, -needed to make our server work. - -When adding or removing functions from our REST API, we can just add or remove functions to those -business logic units. We can also create new logical units when they are added to our REST API. - -### [main.go](./example/main.go) - -The main function is pretty straight forward. We initiate our business logic units. -Then create a config for our rest API. We then create a standard `http.Handler` which we can -update with middleware, test with `httptest`, or to use with other standard tools. -The last piece is to run the handler with `http.ListenAndServe` or to use it with an `http.Server` - -it is all very customizable. - -```go -func main() { - // Initiate business logic implementers. - // This is the main function, so here the implementers' dependencies can be - // injected, such as database, parameters from environment variables, or different - // clients for different APIs. - p := internal.Pet{} - s := internal.Store{} - - // Initiate the http handler, with the objects that are implementing the business logic. - h, err := restapi.Handler(restapi.Config{ - PetAPI: &p, - StoreAPI: &s, - Logger: log.Printf, - }) - if err != nil { - log.Fatal(err) - } - - // Run the standard http server - log.Fatal(http.ListenAndServe(":8080", h)) -} -``` - -## Client - -The client code is in the [client package](https://github.com/Stratoscale/swagger/tree/master/example/client) and is autogenerated. - -To create a new client we use the `client.Config` struct: - -```go -type Config struct { - // URL is the base URL of the upstream server - URL *url.URL - // Transport is an inner transport for the client - Transport http.RoundTripper -} -``` - -This enables us to use custom server endpoint or custom client middleware. Easily, with the -standard components, and with any library that accepts them. - -The client is then generated with the New method: - -```go -// New creates a new swagger petstore HTTP client. -func New(c Config) *SwaggerPetstore { ... } -``` - -This method returns an object that has two important fields: - -```go -type SwaggerPetstore { - ... - Pet *pet.Client - Store *store.Client -} -``` - -Those fields are objects, which implements interfaces declared in the [pet](./example/client/pet) and -[store](./example/client/store) packages: - -For example: - -```go -// API is the interface of the pet client -type API interface { - // PetCreate adds a new pet to the store - PetCreate(ctx context.Context, params *PetCreateParams) (*PetCreateCreated, error) - // PetDelete deletes a pet - PetDelete(ctx context.Context, params *PetDeleteParams) (*PetDeleteNoContent, error) - // PetGet gets pet by it s ID - PetGet(ctx context.Context, params *PetGetParams) (*PetGetOK, error) - // PetList lists pets - PetList(ctx context.Context, params *PetListParams) (*PetListOK, error) - // PetUpdate updates an existing pet - PetUpdate(ctx context.Context, params *PetUpdateParams) (*PetUpdateCreated, error) -} -``` - -They are very similar to the server interfaces, and can be used by consumers of those APIs -(instead of using the actual client or the `*Pet` struct) - -# Authentication - -Authenticating and policy enforcement of the application is done in several stages, described below. - -## Define security in swagger.yaml - -Add to the root of the swagger.yaml the security and security definitions sections. - -```yaml -securityDefinitions: - token: - type: apiKey - in: header - name: Cookie - -security: - - token: [] -``` - -The securityDefinitions section defines different security types that your application can handle. -The supported types by go-swagger are: -* `apiKey` - token that should be able to processed. -* `oauth2` - token and scopes that should be processed. -* and `basic` - user/password that should be processed. - -Here we defined an apiKey, that is passed through the Cookie header. - -The `security` section defines the default security enforcement for the application. You can select -different securityDefinitions, as the keys, and apply "scopes" as the values. Those default definitions -can be overridden in each route by a section with the same name: - -```yaml -paths: - /pets: - post: - [...] - security: - - token: [admin] -``` - -Here we overridden the scope of token in the POST /pets URL so that only admin can use this API. - -Let's see how we can use this functionality. - -## Writing Security Handlers - -Once we created a security definition named "token", a function called "AuthToken" was added to the `restapi.Config`: - -```go -type Config struct { - ... - // AuthToken Applies when the "Cookie" header is set - AuthToken func(token string) (interface{}, error) -} -``` - -This function gets the content of the Cookie header, and should return an `interface{}` and `error`. -The `interface{}` is the object that should represent the user that performed the request, it should -be nil to return an unauthorized 401 HTTP response. If the returned `error` is not nil, an HTTP 500, -internal server error will be returned. - -The returned object, will be stored in the request context under the `restapi.AuthKey` key. - -There is another function that we should know about, in the `restapi.Config` struct: - -```go -type Config struct { - ... - // Authorizer is used to authorize a request after the Auth function was called using the "Auth*" functions - // and the principal was stored in the context in the "AuthKey" context value. - Authorizer func(*http.Request) error -} -``` - -This one is a custom defined function that gets the request and can return an error. -If the returned error is not nil, and 403 HTTP error will be returned to the client - here the policy -enforcement comes to place. -There are two things that this function should be aware of: - -1. The user - it can retrieve the user information from the context: `ctx.Value(restapi.AuthKey).(MyUserType)`. - Usually, a server will have a function for extracting this user information and returns a concrete - type which could be used by all the routes. -2. The route - it can retrieve the route using the go-swagger function: `middleware.MatchedRouteFrom(*http.Request)`. - So no need to parse URL and test the request method. - This route struct contains the route information. If for example, we want to check the scopes that were - defined for the current route in the swagger.yaml we can use the code below: - -```go -for _, auth := range route.Authenticators { - for scopeName, scopeValues := range auth.Scopes { - for _, scopeValue := range scopeValues { - ... - } - } -} -``` diff --git a/tools/swagger/templates/client/client.gotmpl b/tools/swagger/templates/client/client.gotmpl deleted file mode 100644 index 0c77c9c..0000000 --- a/tools/swagger/templates/client/client.gotmpl +++ /dev/null @@ -1,92 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - - -{{ if .Copyright -}}// {{ comment .Copyright -}}{{ end }} - - -package {{ .Name }} - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - -import ( - "net/http" - "github.com/go-openapi/errors" - "github.com/go-openapi/swag" - "github.com/go-openapi/runtime" - "github.com/go-openapi/validate" - - strfmt "github.com/go-openapi/strfmt" - - {{ imports .DefaultImports }} - {{ imports .Imports }} -) - -//go:generate mockery -name API -inpkg - -// API is the interface of the {{ humanize .Name }} client -type API interface { -{{ range .Operations -}} -/* -{{ pascalize .Name }} {{ if .Summary }}{{ pluralizeFirstWord (humanize .Summary) }}{{ if .Description }} - -{{ blockcomment .Description }}{{ end }}{{ else if .Description}}{{ blockcomment .Description }}{{ else }}{{ humanize .Name }} API{{ end -}} -*/ - {{ pascalize .Name }}(ctx context.Context, params *{{ pascalize .Name }}Params{{ if .HasStreamingResponse }}, writer io.Writer{{ end }}) {{ if .SuccessResponse }}({{ range .SuccessResponses }}*{{ pascalize .Name }}, {{ end }}{{ end }}error{{ if .SuccessResponse }}){{ end }} -{{ end -}} -} - -// New creates a new {{ humanize .Name }} API client. -func New(transport runtime.ClientTransport, formats strfmt.Registry, authInfo runtime.ClientAuthInfoWriter) *Client { - return &Client{ - transport: transport, - formats: formats, - authInfo: authInfo, - } -} - -/* -Client {{ if .Summary }}{{ .Summary }}{{ if .Description }} - -{{ blockcomment .Description }}{{ end }}{{ else if .Description}}{{ blockcomment .Description }}{{ else }}for {{ humanize .Name }} API{{ end }} -*/ -type Client struct { - transport runtime.ClientTransport - formats strfmt.Registry - authInfo runtime.ClientAuthInfoWriter -} - -{{ range .Operations -}} -/* -{{ pascalize .Name }} {{ if .Summary }}{{ pluralizeFirstWord (humanize .Summary) }}{{ if .Description }} - -{{ blockcomment .Description }}{{ end }}{{ else if .Description}}{{ blockcomment .Description }}{{ else }}{{ humanize .Name }} API{{ end }} -*/ -func (a *Client) {{ pascalize .Name }}(ctx context.Context, params *{{ pascalize .Name }}Params{{ if .HasStreamingResponse }}, writer io.Writer{{ end }}) {{ if .SuccessResponse }}({{ range .SuccessResponses }}*{{ pascalize .Name }}, {{ end }}{{ end }}error{{ if .SuccessResponse }}){{ end }} { - {{ $length := len .SuccessResponses }} - {{ if .SuccessResponse }}result{{else}}_{{ end }}, err := a.transport.Submit(&runtime.ClientOperation{ - ID: {{ printf "%q" .Name }}, - Method: {{ printf "%q" .Method }}, - PathPattern: {{ printf "%q" .Path }}, - ProducesMediaTypes: {{ printf "%#v" .ProducesMediaTypes }}, - ConsumesMediaTypes: {{ printf "%#v" .ConsumesMediaTypes }}, - Schemes: {{ printf "%#v" .Schemes }}, - Params: params, - Reader: &{{ pascalize .Name }}Reader{formats: a.formats{{ if .HasStreamingResponse }}, writer: writer{{ end }}}, - {{ if .Authorized -}} - AuthInfo: a.authInfo, - {{ end -}} - Context: ctx, - Client: params.HTTPClient, - }) - if err != nil { - return {{ if .SuccessResponse }}{{ padSurround "nil" "nil" 0 $length }}, {{ end }}err - } - {{ if .SuccessResponse }}{{ if eq $length 1 }}return result.(*{{ pascalize .SuccessResponse.Name }}), nil{{ else }}switch value := result.(type) { {{ range $i, $v := .SuccessResponses }} - case *{{ pascalize $v.Name }}: - return {{ padSurround "value" "nil" $i $length }}, nil{{ end }} } - return {{ padSurround "nil" "nil" 0 $length }}, nil{{ end }} - {{ else }}return nil{{ end }} - -} -{{ end }} diff --git a/tools/swagger/templates/client/facade.gotmpl b/tools/swagger/templates/client/facade.gotmpl deleted file mode 100644 index 2c0f8fe..0000000 --- a/tools/swagger/templates/client/facade.gotmpl +++ /dev/null @@ -1,83 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - - -{{ if .Copyright -}}// {{ comment .Copyright -}}{{ end }} - - -package {{ .Package }} - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - - -import ( - "net/url" - "net/http" - - rtclient "github.com/go-openapi/runtime/client" - "github.com/go-openapi/swag" - "github.com/go-openapi/spec" - "github.com/go-openapi/errors" - "github.com/go-openapi/runtime" - "github.com/go-openapi/strfmt" - - {{ imports .DefaultImports }} - {{ imports .Imports }} -) - -const ( - // DefaultHost is the default Host - // found in Meta (info) section of spec file - DefaultHost string = {{ printf "%#v" .Host }} - // DefaultBasePath is the default BasePath - // found in Meta (info) section of spec file - DefaultBasePath string = {{ printf "%#v" .BasePath }} -) - -// DefaultSchemes are the default schemes found in Meta (info) section of spec file -var DefaultSchemes = {{ printf "%#v" .Schemes }} - -type Config struct { - // URL is the base URL of the upstream server - URL *url.URL - // Transport is an inner transport for the client - Transport http.RoundTripper - // AuthInfo is for authentication - AuthInfo runtime.ClientAuthInfoWriter -} - -// New creates a new {{ humanize .Name }} HTTP client. -func New(c Config) *{{ pascalize .Name }} { - var ( - host = DefaultHost - basePath = DefaultBasePath - schemes = DefaultSchemes - ) - - if c.URL != nil { - host = c.URL.Host - basePath = c.URL.Path - schemes = []string{c.URL.Scheme} - } - - transport := rtclient.New(host, basePath, schemes) - if c.Transport != nil { - transport.Transport = c.Transport - } - - cli := new({{ pascalize .Name }}) - cli.Transport = transport - {{ range .OperationGroups -}} - cli.{{ pascalize .Name }} = {{ .PackageAlias }}.New(transport, strfmt.Default, c.AuthInfo) - {{ end -}} - - return cli -} - -// {{ pascalize .Name }} is a client for {{ humanize .Name }} -type {{ pascalize .Name }} struct { - {{ range .OperationGroups -}} - {{ pascalize .Name }} *{{ .PackageAlias }}.Client - {{ end -}} - Transport runtime.ClientTransport -} diff --git a/tools/swagger/templates/server/builder.gotmpl b/tools/swagger/templates/server/builder.gotmpl deleted file mode 100644 index e83d397..0000000 --- a/tools/swagger/templates/server/builder.gotmpl +++ /dev/null @@ -1,466 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - - -{{ if .Copyright -}}// {{ comment .Copyright -}}{{ end }} - - -package {{.Package}} -{{ $package := .Package }} - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - -import ( - "context" - "fmt" - "io" - "net/http" - "strings" - - "github.com/go-openapi/errors" - "github.com/go-openapi/loads" - "github.com/go-openapi/runtime" - "github.com/go-openapi/runtime/middleware" - "github.com/go-openapi/runtime/security" - "github.com/go-openapi/spec" - "github.com/go-openapi/strfmt" - "github.com/go-openapi/swag" - - {{ imports .DefaultImports }} - {{ imports .Imports }} -) - -// New{{ pascalize .Name }}API creates a new {{ pascalize .Name }} instance -func New{{ pascalize .Name }}API(spec *loads.Document) *{{ pascalize .Name }}API { - return &{{ pascalize .Name }}API{ - handlers: make(map[string]map[string]http.Handler), - formats: strfmt.Default, - defaultConsumes: "{{ .DefaultConsumes }}", - defaultProduces: "{{ .DefaultProduces }}", - customConsumers: make(map[string]runtime.Consumer), - customProducers: make(map[string]runtime.Producer), - operationMiddlewares: make(map[string]middleware.Builder), - PreServerShutdown: func() { }, - ServerShutdown: func() { }, - spec: spec, - useSwaggerUI: false, - ServeError: errors.ServeError, - BasicAuthenticator: security.BasicAuth, - APIKeyAuthenticator: security.APIKeyAuth, - BearerAuthenticator: security.BearerAuth, - {{ range .Consumes }} - {{- if .Implementation }} - {{ pascalize .Name }}Consumer: {{ .Implementation }}, - {{- else }} - {{ pascalize .Name }}Consumer: runtime.ConsumerFunc(func(r io.Reader, target interface{}) error { - return errors.NotImplemented("{{.Name}} consumer has not yet been implemented") - }), - {{- end }} - {{- end }} - {{ range .Produces }} - {{- if .Implementation }} - {{ pascalize .Name }}Producer: {{ .Implementation }}, - {{- else }} - {{ pascalize .Name }}Producer: runtime.ProducerFunc(func(w io.Writer, data interface{}) error { - return errors.NotImplemented("{{.Name}} producer has not yet been implemented") - }), - {{- end }} - {{- end }} - {{ range .Operations }} - {{ if ne .Package $package }}{{ pascalize .Package }}{{ end }}{{ pascalize .Name }}Handler: - {{- if ne .Package $package }}{{ .PackageAlias }}.{{ end }}{{ pascalize .Name }}HandlerFunc(func(params {{ if ne .Package $package }}{{ .PackageAlias }}.{{end }} - {{- if $.GenOpts.StrictResponders}} - {{- pascalize .Name }}Params{{if .Authorized}}, principal {{if not ( eq .Principal "interface{}" )}}*{{ end }}{{.Principal}}{{end}}) {{if ne .Package $package }}{{ .Package }}.{{ end }}{{ pascalize .Name }}Responder { - return {{if ne .Package $package }}{{ .Package }}.{{ end }}{{ pascalize .Name }}NotImplemented() - {{else}} - {{- pascalize .Name }}Params{{if .Authorized}}, principal {{if not ( eq .Principal "interface{}" )}}*{{ end }}{{.Principal}}{{end}}) middleware.Responder { - return middleware.NotImplemented("operation {{ if ne .Package $package }}{{ .Package }}.{{ end }}{{pascalize .Name}} has not yet been implemented") - {{ end -}} - }), - {{- end }} - {{ range .SecurityDefinitions }} - {{- if .IsBasicAuth }} - // Applies when the Authorization header is set with the Basic scheme - {{ pascalize .ID }}Auth: func(user string, pass string) ({{if not ( eq .Principal "interface{}" )}}*{{ end }}{{.Principal}}, error) { - return nil, errors.NotImplemented("basic auth ({{ .ID }}) has not yet been implemented") - }, - {{- end }} - {{- if .IsAPIKeyAuth }} - // Applies when the "{{ .Name }}" {{ .Source }} is set - {{ pascalize .ID }}Auth: func(token string) ({{if not ( eq .Principal "interface{}" )}}*{{ end }}{{.Principal}}, error) { - return nil, errors.NotImplemented("api key auth ({{ .ID }}) {{.Name}} from {{.Source}} param [{{ .Name }}] has not yet been implemented") - }, - {{- end }} - {{- if .IsOAuth2 }} - {{ pascalize .ID }}Auth: func(token string, scopes []string) ({{if not ( eq .Principal "interface{}" )}}*{{ end }}{{.Principal}}, error) { - return nil, errors.NotImplemented("oauth2 bearer auth ({{ .ID }}) has not yet been implemented") - }, - {{- end }} - {{- end }} - {{- if .SecurityDefinitions }} - // default authorizer is authorized meaning no requests are blocked - APIAuthorizer: security.Authorized(), - {{- end }} - } -} - -/*{{ pascalize .Name }}API {{ if .Info }}{{ if .Info.Description }}{{.Info.Description}}{{ else }}the {{ humanize .Name }} API{{ end }}{{ end }} */ -type {{ pascalize .Name }}API struct { - spec *loads.Document - context *middleware.Context - handlers map[string]map[string]http.Handler - formats strfmt.Registry - customConsumers map[string]runtime.Consumer - customProducers map[string]runtime.Producer - defaultConsumes string - defaultProduces string - Middleware func(middleware.Builder) http.Handler - useSwaggerUI bool - - // operationMiddlewares middleware for operations - operationMiddlewares map[string]middleware.Builder - - // BeforePrepare is called before the Prepare of the operation - BeforePrepare func(context.Context, string, interface{}) middleware.Responder - - // BasicAuthenticator generates a runtime.Authenticator from the supplied basic auth function. - // It has a default implementation in the security package, however you can replace it for your particular usage. - BasicAuthenticator func(security.UserPassAuthentication) runtime.Authenticator - // APIKeyAuthenticator generates a runtime.Authenticator from the supplied token auth function. - // It has a default implementation in the security package, however you can replace it for your particular usage. - APIKeyAuthenticator func(string, string, security.TokenAuthentication) runtime.Authenticator - // BearerAuthenticator generates a runtime.Authenticator from the supplied bearer token auth function. - // It has a default implementation in the security package, however you can replace it for your particular usage. - BearerAuthenticator func(string, security.ScopedTokenAuthentication) runtime.Authenticator - {{ range .Consumes }} - // {{ pascalize .Name }}Consumer registers a consumer for the following mime types: - {{- range .AllSerializers }} - // - {{ .MediaType }} - {{- end }} - {{ pascalize .Name }}Consumer runtime.Consumer - {{- end }} - {{ range .Produces}} - // {{ pascalize .Name }}Producer registers a producer for the following mime types: - {{- range .AllSerializers }} - // - {{ .MediaType }} - {{- end }} - {{ pascalize .Name }}Producer runtime.Producer - {{- end }} - {{ range .SecurityDefinitions}} - {{- if .IsBasicAuth}} - - // {{ pascalize .ID }}Auth registers a function that takes username and password and returns a principal - // it performs authentication with basic auth - {{ pascalize .ID }}Auth func(string, string) ({{ if not ( eq .Principal "interface{}" ) }}*{{ end }}{{ .Principal }}, error) - {{- end }} - {{- if .IsAPIKeyAuth}} - - // {{ pascalize .ID }}Auth registers a function that takes a token and returns a principal - // it performs authentication based on an api key {{ .Name }} provided in the {{.Source}} - {{ pascalize .ID }}Auth func(string) ({{ if not ( eq .Principal "interface{}" ) }}*{{ end }}{{ .Principal }}, error) - {{- end }} - {{- if .IsOAuth2 }} - - // {{ pascalize .ID }}Auth registers a function that takes an access token and a collection of required scopes and returns a principal - // it performs authentication based on an oauth2 bearer token provided in the request - {{ pascalize .ID }}Auth func(string, []string) ({{ if not ( eq .Principal "interface{}" ) }}*{{ end }}{{ .Principal }}, error) - {{- end }} - {{- end }} - {{- if .SecurityDefinitions }} - - // APIAuthorizer provides access control (ACL/RBAC/ABAC) by providing access to the request and authenticated principal - APIAuthorizer runtime.Authorizer - {{- end }} - {{- $package := .Package }} - {{ range .Operations }} - // {{ if ne .Package $package }}{{ pascalize .Package }}{{ end }}{{ pascalize .Name }}Handler sets the operation handler for the {{ humanize .Name }} operation - {{ if ne .Package $package }}{{ pascalize .Package }}{{ end }}{{ pascalize .Name }}Handler {{ if ne .Package $package }}{{ .PackageAlias }}.{{ end }}{{ pascalize .Name }}Handler - {{- end }} - // ServeError is called when an error is received, there is a default handler - // but you can set your own with this - ServeError func(http.ResponseWriter, *http.Request, error) - - // PreServerShutdown is called before the HTTP(S) server is shutdown - // This allows for custom functions to get executed before the HTTP(S) server stops accepting traffic - PreServerShutdown func() - - // ServerShutdown is called when the HTTP(S) server is shut down and done - // handling all active connections and does not accept connections any more - ServerShutdown func() - - // Custom command line argument groups with their descriptions - CommandLineOptionsGroups []swag.CommandLineOptionsGroup - - // User defined logger function. - Logger func(string, ...interface{}) -} - -// UseRedoc for documentation at /docs -func ({{.ReceiverName}} *{{ pascalize .Name }}API) UseRedoc() { - {{.ReceiverName}}.useSwaggerUI = false -} - -// UseSwaggerUI for documentation at /docs -func ({{.ReceiverName}} *{{ pascalize .Name }}API) UseSwaggerUI() { - {{.ReceiverName}}.useSwaggerUI = true -} - -// SetDefaultProduces sets the default produces media type -func ({{.ReceiverName}} *{{ pascalize .Name }}API) SetDefaultProduces(mediaType string) { - {{.ReceiverName}}.defaultProduces = mediaType -} - -// SetDefaultConsumes returns the default consumes media type -func ({{.ReceiverName}} *{{ pascalize .Name }}API) SetDefaultConsumes(mediaType string) { - {{.ReceiverName}}.defaultConsumes = mediaType -} - -// SetSpec sets a spec that will be served for the clients. -func ({{.ReceiverName}} *{{ pascalize .Name }}API) SetSpec(spec *loads.Document) { - {{.ReceiverName}}.spec = spec -} - -// DefaultProduces returns the default produces media type -func ({{.ReceiverName}} *{{ pascalize .Name }}API) DefaultProduces() string { - return {{.ReceiverName}}.defaultProduces -} - -// DefaultConsumes returns the default consumes media type -func ({{.ReceiverName}} *{{ pascalize .Name }}API) DefaultConsumes() string { - return {{.ReceiverName}}.defaultConsumes -} - -// Formats returns the registered string formats -func ({{.ReceiverName}} *{{ pascalize .Name }}API) Formats() strfmt.Registry { - return {{.ReceiverName}}.formats -} - -// RegisterFormat registers a custom format validator -func ({{.ReceiverName}} *{{ pascalize .Name }}API) RegisterFormat(name string, format strfmt.Format, validator strfmt.Validator) { - {{.ReceiverName}}.formats.Add(name, format, validator) -} - -// Validate validates the registrations in the {{ pascalize .Name }}API -func ({{.ReceiverName}} *{{ pascalize .Name }}API) Validate() error { - var unregistered []string - {{ range .Consumes }} - if {{.ReceiverName}}.{{ pascalize .Name }}Consumer == nil { - unregistered = append(unregistered, "{{ pascalize .Name }}Consumer") - } - {{- end }} - {{ range .Produces }} - if {{.ReceiverName}}.{{ pascalize .Name }}Producer == nil { - unregistered = append(unregistered, "{{ pascalize .Name }}Producer") - } - {{- end }} - {{ range .SecurityDefinitions }} - if {{.ReceiverName}}.{{ pascalize .ID }}Auth == nil { - unregistered = append(unregistered, "{{if .IsAPIKeyAuth }}{{ pascalize .Name }}{{ else }}{{ pascalize .ID }}{{ end }}Auth") - } - {{- end }} - {{ range .Operations }} - if {{.ReceiverName}}.{{ if ne .Package $package }}{{ pascalize .Package }}{{ end }}{{ pascalize .Name }}Handler == nil { - unregistered = append(unregistered, "{{ if ne .Package $package }}{{ .Package }}.{{ end }}{{ pascalize .Name }}Handler") - } - {{- end }} - - if len(unregistered) > 0 { - return fmt.Errorf("missing registration: %s", strings.Join(unregistered, ", ")) - } - - return nil -} -// ServeErrorFor gets a error handler for a given operation id -func ({{.ReceiverName}} *{{ pascalize .Name }}API) ServeErrorFor(operationID string) func(http.ResponseWriter, *http.Request, error) { - return {{.ReceiverName}}.ServeError -} -// AuthenticatorsFor gets the authenticators for the specified security schemes -func ({{.ReceiverName}} *{{ pascalize .Name }}API) AuthenticatorsFor(schemes map[string]spec.SecurityScheme) map[string]runtime.Authenticator { - {{- if .SecurityDefinitions }} - result := make(map[string]runtime.Authenticator) - for name := range schemes { - switch name { - {{- range .SecurityDefinitions }} - case "{{.ID}}": - {{- if .IsBasicAuth }} - result[name] = {{.ReceiverName}}.BasicAuthenticator({{ if not ( eq .Principal "interface{}" ) }}func(username, password string) (interface{}, error) { - return {{ end }}{{.ReceiverName}}.{{ pascalize .ID }}Auth{{ if not ( eq .Principal "interface{}" ) }}(username, password) - }{{ end }}) - {{- end }} - {{- if .IsAPIKeyAuth }} - scheme := schemes[name] - result[name] = {{.ReceiverName}}.APIKeyAuthenticator(scheme.Name, scheme.In, {{ if not ( eq .Principal "interface{}" ) }}func(token string) (interface{}, error) { - return {{ end }}{{.ReceiverName}}.{{ pascalize .ID }}Auth{{ if not ( eq .Principal "interface{}" ) }}(token) - }{{ end }}) - {{- end }} - {{- if .IsOAuth2 }} - result[name] = {{.ReceiverName}}.BearerAuthenticator(name, {{ if not ( eq .Principal "interface{}" ) }}func(token string, scopes []string) (interface{}, error) { - return {{ end }}{{.ReceiverName}}.{{ pascalize .ID }}Auth{{ if not ( eq .Principal "interface{}" ) }}(token, scopes) - }{{ end }}) - {{- end }} - {{end}} - } - } - return result - {{- else }} - return nil - {{- end }} -} - -// Authorizer returns the registered authorizer -func ({{.ReceiverName}} *{{ pascalize .Name }}API) Authorizer() runtime.Authorizer { - {{- if .SecurityDefinitions }} - return {{.ReceiverName}}.APIAuthorizer - {{- else }} - return nil - {{- end }} -} - -// ConsumersFor gets the consumers for the specified media types. -// MIME type parameters are ignored here. -func ({{.ReceiverName}} *{{ pascalize .Name }}API) ConsumersFor(mediaTypes []string) map[string]runtime.Consumer { - {{- if .Consumes }} - result := make(map[string]runtime.Consumer, len(mediaTypes)) - for _, mt := range mediaTypes { - switch mt { - {{- range .Consumes }} - {{- range .AllSerializers }} - case "{{ .MediaType }}": - result["{{ .MediaType }}"] = {{.ReceiverName}}.{{ pascalize .Name }}Consumer - {{- end }} - {{- end }} - } - - if c, ok := {{.ReceiverName}}.customConsumers[mt]; ok { - result[mt] = c - } - } - return result - {{- else }} - return nil - {{- end }} -} - -// ProducersFor gets the producers for the specified media types. -// MIME type parameters are ignored here. -func ({{.ReceiverName}} *{{ pascalize .Name }}API) ProducersFor(mediaTypes []string) map[string]runtime.Producer { - {{- if .Produces }} - result := make(map[string]runtime.Producer, len(mediaTypes)) - for _, mt := range mediaTypes { - switch mt { - {{- range .Produces }} - {{- range .AllSerializers }} - case "{{ .MediaType }}": - result["{{ .MediaType }}"] = {{.ReceiverName}}.{{ pascalize .Name }}Producer - {{- end }} - {{- end }} - } - - if p, ok := {{.ReceiverName}}.customProducers[mt]; ok { - result[mt] = p - } - } - return result - {{- else }} - return nil - {{- end }} -} - -// HandlerFor gets a http.Handler for the provided operation method and path -func ({{.ReceiverName}} *{{ pascalize .Name }}API) HandlerFor(method, path string) (http.Handler, bool) { - if {{.ReceiverName}}.handlers == nil { - return nil, false - } - um := strings.ToUpper(method) - if _, ok := {{.ReceiverName}}.handlers[um]; !ok { - return nil, false - } - if path == "/" { - path = "" - } - h, ok := {{.ReceiverName}}.handlers[um][path] - return h, ok -} - -// Context returns the middleware context for the {{ humanize .Name }} API -func ({{.ReceiverName}} *{{ pascalize .Name }}API) Context() *middleware.Context { - if {{.ReceiverName}}.context == nil { - {{.ReceiverName}}.context = middleware.NewRoutableContext({{.ReceiverName}}.spec, {{.ReceiverName}}, nil) - } - - return {{ .ReceiverName }}.context -} - -func ({{.ReceiverName}} *{{ pascalize .Name }}API) handler(operation string, next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - h := next - if b, ok := {{.ReceiverName}}.operationMiddlewares[operation]; ok { - h = b(h) - } - - h.ServeHTTP(w, r) - }) -} - -func ({{.ReceiverName}} *{{ pascalize .Name }}API) initHandlerCache() { - {{.ReceiverName}}.Context() // don't care about the result, just that the initialization happened - {{- if .Operations }} - if {{ .ReceiverName }}.handlers == nil { - {{.ReceiverName}}.handlers = make(map[string]map[string]http.Handler) - } - {{ range .Operations }} - if {{ .ReceiverName }}.handlers[{{ printf "%q" (upper .Method) }}] == nil { - {{ .ReceiverName }}.handlers[{{ printf "%q" (upper .Method) }}] = make(map[string]http.Handler) - } - {{.ReceiverName}}.handlers[{{ printf "%q" (upper .Method) }}][{{ if eq .Path "/" }}""{{ else }}{{ printf "%q" (cleanPath .Path) }}{{ end }}] = {{ .ReceiverName }}.handler("{{ pascalize .Name }}", {{ if ne .Package $package }}{{ .PackageAlias }}.{{ end }}New{{ pascalize .Name }}({{.ReceiverName}}.context, {{.ReceiverName}}.{{if ne .Package $package}}{{ pascalize .Package }}{{end}}{{ pascalize .Name }}Handler)) - {{- end }} - {{- end }} -} - -// Serve creates a http handler to serve the API over HTTP -// can be used directly in http.ListenAndServe(":8000", api.Serve(nil)) -func ({{.ReceiverName}} *{{ pascalize .Name }}API) Serve(builder middleware.Builder) http.Handler { - {{ .ReceiverName }}.Init() - - if {{ .ReceiverName}}.Middleware != nil { - return {{ .ReceiverName }}.Middleware(builder) - } - if {{.ReceiverName}}.useSwaggerUI { - return {{.ReceiverName}}.context.APIHandlerSwaggerUI(builder) - } - return {{.ReceiverName}}.context.APIHandler(builder) -} - -// Init allows you to just initialize the handler cache, you can then recompose the middleware as you see fit -func ({{.ReceiverName}} *{{ pascalize .Name }}API) Init() { - if len({{.ReceiverName}}.handlers) == 0 { - {{.ReceiverName}}.initHandlerCache() - } -} - -// RegisterConsumer allows you to add (or override) a consumer for a media type. -func ({{.ReceiverName}} *{{ pascalize .Name }}API) RegisterConsumer(mediaType string, consumer runtime.Consumer) { - {{.ReceiverName}}.customConsumers[mediaType] = consumer -} - -// RegisterProducer allows you to add (or override) a producer for a media type. -func ({{.ReceiverName}} *{{ pascalize .Name }}API) RegisterProducer(mediaType string, producer runtime.Producer) { - {{.ReceiverName}}.customProducers[mediaType] = producer -} - -// AddMiddlewareFor adds a http middleware to existing handler -func ({{.ReceiverName}} *{{ pascalize .Name }}API) AddMiddlewareFor(method, path string, builder middleware.Builder) { - um := strings.ToUpper(method) - if path == "/" { - path = "" - } - {{.ReceiverName}}.Init() - if h, ok := {{.ReceiverName}}.handlers[um][path]; ok { - {{.ReceiverName}}.handlers[method][path] = builder(h) - } -} - -// RegisterMiddleware allows you to add (or override) a middleware for operation. -func ({{.ReceiverName}} *{{ pascalize .Name }}API) RegisterMiddleware(operation string, builder middleware.Builder) { - {{.ReceiverName}}.operationMiddlewares[operation] = builder -} diff --git a/tools/swagger/templates/server/configureapi.gotmpl b/tools/swagger/templates/server/configureapi.gotmpl deleted file mode 100644 index 10d6cbb..0000000 --- a/tools/swagger/templates/server/configureapi.gotmpl +++ /dev/null @@ -1,210 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - - -{{ if .Copyright -}}// {{ comment .Copyright -}}{{ end }} - - -package {{ .APIPackage }} - -import ( - "context" - "crypto/tls" - "net/http" - "log" - "fmt" - - "github.com/go-openapi/errors" - "github.com/go-openapi/loads" - "github.com/go-openapi/runtime" - "github.com/go-openapi/runtime/middleware" - "github.com/go-openapi/runtime/security" - - {{ imports .DefaultImports }} - {{ imports .Imports }} -) -{{ $package := .Package }} - -type contextKey string - -const AuthKey contextKey = "Auth" - -{{ range .OperationGroups -}} -// go:generate mockery -name {{ pascalize .Name}}API -inpkg - -/* {{ pascalize .Name }}API {{ .Description }} */ -type {{ pascalize .Name }}API interface { - /* Prepare action before the operation */ - Prepare(ctx context.Context, operation string, params interface{}) middleware.Responder - -{{ range .Operations -}} - {{ if .Summary -}} - /* {{ pascalize .Name }} {{ .Summary }} */ - {{ else if .Description -}} - /* {{ pascalize .Name }} {{ .Description }} */ - {{ end -}} - {{ pascalize .Name }}(ctx context.Context, params {{.Package}}.{{ pascalize .Name }}Params) middleware.Responder - -{{ end -}} -} -{{ end }} - -// Config is configuration for Handler -type Config struct { - {{ range .OperationGroups -}} - {{ pascalize .Name }}API - {{ end -}} - Logger func(string, ...interface{}) - // InnerMiddleware is for the handler executors. These do not apply to the swagger.json document. - // The middleware executes after routing but before authentication, binding and validation - InnerMiddleware func(http.Handler) http.Handler - - // Authorizer is used to authorize a request after the Auth function was called using the "Auth*" functions - // and the principal was stored in the context in the "AuthKey" context value. - Authorizer func(*http.Request) error - - {{ range .SecurityDefinitions -}} - {{ if .IsBasicAuth -}} - // Auth{{ pascalize .ID }} for basic authentication - Auth{{ pascalize .ID }} func(user string, pass string) (interface{}, error) - {{ end -}} - {{ if .IsAPIKeyAuth -}} - // Auth{{ pascalize .ID }} Applies when the "{{ .Name }}" {{ .Source }} is set - Auth{{ pascalize .ID }} func(token string) (interface{}, error) - {{ end }} - {{ if .IsOAuth2 -}} - // Auth{{ pascalize .ID }} For OAuth2 authentication - Auth{{ pascalize .ID }} func(token string, scopes []string) (interface{}, error) - {{ end -}} - {{ end -}} - - // Authenticator to use for all APIKey authentication - APIKeyAuthenticator func(string, string, security.TokenAuthentication) runtime.Authenticator - // Authenticator to use for all Bearer authentication - BasicAuthenticator func(security.UserPassAuthentication) runtime.Authenticator - // Authenticator to use for all Basic authentication - BearerAuthenticator func(string, security.ScopedTokenAuthentication) runtime.Authenticator -} - -// Handler returns an http.Handler given the handler configuration -// It mounts all the business logic implementers in the right routing. -func Handler(c Config) (http.Handler, error) { - h, _, err := HandlerAPI(c) - return h, err -} - -// HandlerAPI returns an http.Handler given the handler configuration -// and the corresponding *{{ pascalize .Name }} instance. -// It mounts all the business logic implementers in the right routing. -func HandlerAPI(c Config) (http.Handler, *{{.Package}}.{{ pascalize .Name }}API, error) { - spec, err := loads.Analyzed(swaggerCopy(SwaggerJSON), "") - if err != nil { - return nil, nil, fmt.Errorf("analyze swagger: %v", err) - } - api := {{.Package}}.New{{ pascalize .Name }}API(spec) - api.ServeError = errors.ServeError - api.Logger = c.Logger - - if c.APIKeyAuthenticator != nil { - api.APIKeyAuthenticator = c.APIKeyAuthenticator - } - if c.BasicAuthenticator != nil { - api.BasicAuthenticator = c.BasicAuthenticator - } - if c.BearerAuthenticator != nil { - api.BearerAuthenticator = c.BearerAuthenticator - } - - {{ range .Consumes -}} - {{ if .Implementation -}} - api.{{ pascalize .Name }}Consumer = {{ .Implementation }} - {{ else }} - api.{{ pascalize .Name }}Consumer = runtime.ConsumerFunc(func(r io.Reader, target interface{}) error { - return errors.NotImplemented("{{.Name}} consumer has not yet been implemented") - }) - {{ end -}} - {{ end -}} - {{ range .Produces -}} - {{ if .Implementation -}} - api.{{ pascalize .Name }}Producer = {{ .Implementation }} - {{ else -}} - api.{{ pascalize .Name }}Producer = runtime.ProducerFunc(func(w io.Writer, data interface{}) error { - return errors.NotImplemented("{{.Name}} producer has not yet been implemented") - }) - {{ end -}} - {{ end -}} - - {{ range .SecurityDefinitions -}} - {{ if .IsBasicAuth -}} - api.{{ pascalize .ID }}Auth = func(user string, pass string) ({{if not ( eq .Principal "interface{}" )}}*{{ end }}{{.Principal}}, error) { - if c.Auth{{ pascalize .ID }} == nil { - return "", nil - } - return c.Auth{{ pascalize .ID }}(user, pass) - } - {{ end -}} - {{ if .IsAPIKeyAuth -}} - api.{{ pascalize .ID }}Auth = func(token string) ({{if not ( eq .Principal "interface{}" )}}*{{ end }}{{.Principal}}, error) { - if c.Auth{{ pascalize .ID }} == nil { - return token, nil - } - return c.Auth{{ pascalize .ID }}(token) - } - {{ end }} - {{ if .IsOAuth2 -}} - api.{{ pascalize .ID }}Auth = func(token string, scopes []string) ({{if not ( eq .Principal "interface{}" )}}*{{ end }}{{.Principal}}, error) { - if c.Auth{{ pascalize .ID }} == nil { - return token, nil - } - return c.Auth{{ pascalize .ID }}(token, scopes) - } - {{ end -}} - {{ end -}} - - {{ if .SecurityDefinitions -}} - api.APIAuthorizer = authorizer(c.Authorizer) - {{ end -}} - - {{ range .Operations -}} - api.{{if ne .Package $package}}{{pascalize .Package}}{{end}}{{ pascalize .Name }}Handler = - {{- .PackageAlias }}.{{ pascalize .Name }}HandlerFunc(func(params {{.PackageAlias}}.{{ pascalize .Name }}Params{{if .Authorized}}, principal interface{}{{end}}) middleware.Responder { - ctx := params.HTTPRequest.Context() - {{ if .Authorized -}} - ctx = storeAuth(ctx, principal) - {{ end -}} - if api.BeforePrepare != nil { - if res := api.BeforePrepare(ctx, "{{pascalize .Name}}", ¶ms); res != nil { - return res - } - } - if res := c.{{pascalize .Package}}API.Prepare(ctx, "{{pascalize .Name}}", ¶ms); res != nil { - return res - } - return c.{{pascalize .Package}}API.{{pascalize .Name}}(ctx, params) - }) - {{ end -}} - - api.ServerShutdown = func() { } - return api.Serve(c.InnerMiddleware), api, nil -} - -// swaggerCopy copies the swagger json to prevent data races in runtime -func swaggerCopy(orig json.RawMessage) json.RawMessage { - c := make(json.RawMessage, len(orig)) - copy(c, orig) - return c -} - -// authorizer is a helper function to implement the runtime.Authorizer interface. -type authorizer func(*http.Request) error - -func (a authorizer) Authorize(req *http.Request, principal interface{}) error { - if a == nil { - return nil - } - ctx := storeAuth(req.Context(), principal) - return a(req.WithContext(ctx)) -} - -func storeAuth(ctx context.Context, principal interface{}) context.Context { - return context.WithValue(ctx, AuthKey, principal) -} diff --git a/tools/swagger/templates/server/responses.gotmpl b/tools/swagger/templates/server/responses.gotmpl deleted file mode 100644 index 52793e1..0000000 --- a/tools/swagger/templates/server/responses.gotmpl +++ /dev/null @@ -1,271 +0,0 @@ -{{ define "serverheaderbuilder" }} -{{ if not .IsArray }}{{ template "simpleserverheaderbuilder" . }}{{ else }}{{ template "sliceserverheaderbuilder" . }}{{ end }} -{{- end }} -{{ define "simpleserverheaderbuilder" }} -{{ if .IsNullable -}} -var {{ varname .ID }} string -if {{ .ReceiverName }}.{{ pascalize .ID }} != nil { - {{ varname .ID }} = {{ if .Formatter }}{{ .Formatter }}(*{{ .ReceiverName }}.{{ pascalize .ID }}){{ else }}{{ if not .IsCustomFormatter }}*{{ end }}{{ .ReceiverName }}.{{ pascalize .ID }}{{ if .IsCustomFormatter }}.String(){{end}}{{end}} -} -{{ else }}{{ varname .ID }} := {{ if .Formatter }}{{ .Formatter }}({{ .ReceiverName }}.{{ pascalize .ID }}){{ else }}{{ .ReceiverName }}.{{ pascalize .ID }}{{ if .IsCustomFormatter }}.String(){{end}}{{end}} -{{ end -}} -if {{ varname .ID }} != "" { - rw.Header().Set({{ printf "%q" .Name }}, {{ varname .ID }}) -} -{{ end }} -{{ define "sliceitemserverheaderbuilder" }} -{{ if .IsNullable -}} -var {{ .ValueExpression }}S string -if {{ .ValueExpression }} != nil { - {{ .ValueExpression }}S = {{ if .Formatter }}{{ .Formatter }}(*{{ .ValueExpression }}){{ else }}*{{ .ValueExpression }}{{ if .IsCustomFormatter }}.String(){{end}}{{end}} -} -{{ else -}} -{{ .ValueExpression }}S := {{ if .Formatter }}{{ .Formatter }}({{ .ValueExpression }}){{ else }}{{ .ValueExpression }}{{ if .IsCustomFormatter }}.String(){{end}}{{end}} -{{ end -}} -if {{ .ValueExpression }}S != "" { - {{ .ValueExpression }}R = append({{ .ValueExpression }}R, {{ .ValueExpression }}S) -} -{{ end }} -{{define "sliceserverheaderbuilder" }} -var {{ varname .Child.ValueExpression }}R []string -for _, {{ varname .Child.ValueExpression }} := range {{ .ValueExpression }} { - {{- if not .Child.IsArray }}{{ template "sliceitemserverheaderbuilder" .Child }}{{ else }}{{ template "sliceserverheaderbuilder" .Child }}{{ end -}} -} -{{ if not .Child.Parent -}} -{{ varname .ID }} := swag.JoinByFormat({{ varname .Child.ValueExpression }}R, {{ printf "%q" .CollectionFormat }}) -if len({{ varname .ID }}) > 0 { - hv := {{ varname .ID }}[0] - if hv != "" { - rw.Header().Set({{ printf "%q" .Name }}, hv) - } -} -{{ else -}} -{{ .ValueExpression }}S := swag.JoinByFormat({{ varname .Child.ValueExpression }}R, {{ printf "%q" .CollectionFormat }}) -if len({{ .ValueExpression }}S) > 0 { - {{ .ValueExpression }}Ss := {{ .ValueExpression }}S[0] - if {{ .ValueExpression }}Ss != "" { - {{ .ValueExpression }}R = append({{ .ValueExpression }}R, {{ .ValueExpression }}Ss) - } -} -{{ end -}} -{{ end -}} -{{ define "serverresponse" }} -{{ if ne .Code -1 }}// {{pascalize .Name}}Code is the HTTP code returned for type {{ pascalize .Name}} -const {{ pascalize .Name}}Code int = {{ .Code }}{{ end }} - -/*{{ if .Description }}{{ pascalize .Name }} {{ blockcomment .Description }}{{else}}{{ pascalize .Name }} {{ humanize .Name }}{{end}} - -swagger:response {{ camelize .Name }} -*/ -type {{ pascalize .Name }} struct { - {{ if eq .Code -1 }} - _statusCode int - {{ end }}{{ range .Headers }}/*{{if .Description }}{{ blockcomment .Description }}{{ end }} - {{ if .Maximum }} - Maximum: {{ if .ExclusiveMaximum }}< {{ end }}{{ .Maximum }}{{ end }}{{ if .Minimum }} - Minimum: {{ if .ExclusiveMinimum }}> {{ end }}{{ .Minimum }}{{ end }}{{ if .MultipleOf }} - Multiple Of: {{ .MultipleOf }}{{ end }}{{ if .MaxLength }} - Max Length: {{ .MaxLength }}{{ end }}{{ if .MinLength }} - Min Length: {{ .MinLength }}{{ end }}{{ if .Pattern }} - Pattern: {{ .Pattern }}{{ end }}{{ if .MaxItems }} - Max Items: {{ .MaxItems }}{{ end }}{{ if .MinItems }} - Min Items: {{ .MinItems }}{{ end }}{{ if .UniqueItems }} - Unique: true{{ end }}{{ if .HasDefault }} - Default: {{ printf "%#v" .Default }}{{ end }} - */ - {{ pascalize .Name }} {{ .GoType }} `json:"{{.Name}}{{ if not .Required }},omitempty{{ end }}{{ if .IsJSONString }},string{{ end }}"` - {{ end }} - {{ if .Schema }}{{ with .Schema }} - /*{{if .Description }}{{ blockcomment .Description }}{{ end }}{{ if .Maximum }} - Maximum: {{ if .ExclusiveMaximum }}< {{ end }}{{ .Maximum }}{{ end }}{{ if .Minimum }} - Minimum: {{ if .ExclusiveMinimum }}> {{ end }}{{ .Minimum }}{{ end }}{{ if .MultipleOf }} - Multiple Of: {{ .MultipleOf }}{{ end }}{{ if .MaxLength }} - Max Length: {{ .MaxLength }}{{ end }}{{ if .MinLength }} - Min Length: {{ .MinLength }}{{ end }}{{ if .Pattern }} - Pattern: {{ .Pattern }}{{ end }}{{ if .MaxItems }} - Max Items: {{ .MaxItems }}{{ end }}{{ if .MinItems }} - Min Items: {{ .MinItems }}{{ end }}{{ if .UniqueItems }} - Unique: true{{ end }} - In: Body - */{{ end }} - Payload {{ if and (not .Schema.IsBaseType) .Schema.IsComplexObject }}*{{ end }}{{ .Schema.GoType }} `json:"body,omitempty"` - {{ end }} -} - -// New{{ pascalize .Name }} creates {{ pascalize .Name }} with default headers values -func New{{ pascalize .Name }}({{ if eq .Code -1 }}code int{{ end }}) *{{ pascalize .Name }} { {{ if eq .Code -1 }} -if code <= 0 { - code = 500 - } -{{ end }} -{{ if .Headers.HasSomeDefaults }} - var ( - // initialize headers with default values - {{ range .Headers }} - {{ if .HasDefault -}} - {{ varname .ID}}Default = - {{- if and .IsPrimitive .IsCustomFormatter (not (stringContains .Zero "(\"" )) }}{{ .Zero }}{{/* strfmt type initializer requires UnmarshalText(), e.g. Date, Datetime, Duration */}} - {{- else if and .IsPrimitive .IsCustomFormatter (stringContains .Zero "(\"" ) }}{{.GoType}}({{- printf "%#v" .Default }}){{/* strfmt type initializer takes string */}} - {{- else if and .IsPrimitive (not .IsCustomFormatter) -}}{{.GoType}}({{- printf "%#v" .Default }}){{/* regular go primitive type initializer */}} - {{- else if .IsArray -}}{{- /* Do not initialize from possible defaults in nested arrays */ -}} - {{- if and .Child.IsPrimitive .Child.IsCustomFormatter }}{{ .Zero }}{{/* initialization strategy with UnmarshalText() */}} - {{- else if .Child.IsArray -}}{{ .Zero }}{{/* initialization strategy with json.Unmarshal() */}} - {{- else if and .Child.IsPrimitive (not .Child.IsCustomFormatter) -}}{{.GoType}}{{- arrayInitializer .Default }}{{/* regular go primitive type initializer: simple slice initializer */}} - {{- else }}{{ printf "%#v" .Default }}{{/* all other cases (e.g. schema) [should not occur] */}} - {{- end }} - {{- else }}{{ printf "%#v" .Default }}{{/* case .Schema */}} - {{- end }} - {{- end }} - {{- end }} - ) - -{{ range .Headers }}{{ if .HasDefault -}}{{- /* carry on UnmarshalText initialization strategy */ -}} - {{ if and .IsPrimitive .IsCustomFormatter (not (stringContains .Zero "(\"")) }}{{ varname .ID}}Default.UnmarshalText([]byte({{ printf "%q" .Default }})) - {{ else if .IsArray -}} - {{ if or ( and .Child.IsPrimitive .Child.IsCustomFormatter ) .Child.IsArray -}} - if err := json.Unmarshal([]byte(`{{printf "%s" (json .Default)}}`), &{{ varname .ID }}Default); err != nil { - // panics if specification is invalid - msg := fmt.Sprintf("invalid default value for header {{ varname .ID }}: %v",err) - panic(msg) - } - {{ end -}} - {{- end }} - {{- end }} -{{- end }} -{{ end }} - return &{{ pascalize .Name }}{ - {{ if eq .Code -1 }}_statusCode: code,{{ end }} - {{ range .Headers }}{{ if .HasDefault }} - {{ pascalize .Name}}: {{ if and (not .IsArray) (not .HasDiscriminator) (not .IsInterface) (not .IsStream) .IsNullable }}&{{ end }}{{ varname .ID }}Default, - {{ end }} - {{ end -}} - } -} - -{{ if eq .Code -1 }} -// WithStatusCode adds the status to the {{ humanize .Name }} response -func ({{ .ReceiverName }} *{{ pascalize .Name }}) WithStatusCode(code int) *{{ pascalize .Name }} { - {{ .ReceiverName }}._statusCode = code - return {{ .ReceiverName }} -} - -// SetStatusCode sets the status to the {{ humanize .Name }} response -func ({{ .ReceiverName }} *{{ pascalize .Name }}) SetStatusCode(code int) { - {{ .ReceiverName }}._statusCode = code -} -{{ end }}{{ range .Headers }} -// With{{ pascalize .Name }} adds the {{ camelize .Name }} to the {{ humanize $.Name }} response -func ({{ $.ReceiverName }} *{{ pascalize $.Name }}) With{{ pascalize .Name }}({{ varname .Name }} {{ .GoType}}) *{{ pascalize $.Name }} { - {{ $.ReceiverName }}.{{ pascalize .Name }} = {{ varname .Name }} - return {{ .ReceiverName }} -} - -// Set{{ pascalize .Name }} sets the {{ camelize .Name }} to the {{ humanize $.Name }} response -func ({{ $.ReceiverName }} *{{ pascalize $.Name }}) Set{{ pascalize .Name }}({{ varname .Name }} {{ .GoType}}) { - {{ $.ReceiverName }}.{{ pascalize .Name }} = {{ varname .Name }} -} -{{ end }}{{ if .Schema }} -// WithPayload adds the payload to the {{ humanize .Name }} response -func ({{ .ReceiverName }} *{{ pascalize .Name }}) WithPayload(payload {{ if and .Schema.IsComplexObject (not .Schema.IsBaseType) }}*{{ end }}{{ .Schema.GoType }}) *{{ pascalize .Name }} { - {{ .ReceiverName }}.Payload = payload - return {{ .ReceiverName }} -} - -// SetPayload sets the payload to the {{ humanize .Name }} response -func ({{ .ReceiverName }} *{{ pascalize .Name }}) SetPayload(payload {{ if and .Schema.IsComplexObject (not .Schema.IsBaseType) }}*{{ end }}{{ .Schema.GoType }}) { - {{ .ReceiverName }}.Payload = payload -} -{{ end }} - -// WriteResponse to the client -func ({{ .ReceiverName }} *{{ pascalize .Name }}) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { - {{ range .Headers }} - // response header {{.Name}} - {{ template "serverheaderbuilder" . -}} - {{ end }} - {{ if not .Schema }} - rw.Header().Del(runtime.HeaderContentType) // Remove Content-Type on empty responses - {{ end }} - rw.WriteHeader({{ if eq .Code -1 }}{{ .ReceiverName }}._statusCode{{ else }}{{ .Code }}{{ end }}) - {{- if .Schema }} - {{- if .Schema.IsComplexObject }} - if {{ .ReceiverName }}.Payload != nil { - {{- end }} - payload := {{ .ReceiverName }}.Payload - {{- if and (not .Schema.IsInterface) (or .Schema.IsArray .Schema.IsMap) }} - if payload == nil { - // return empty {{ if .Schema.IsArray }}array{{ else if .Schema.IsMap }}map{{ end }} - payload = - {{- if or .Schema.IsAliased .Schema.IsComplexObject }} - {{- if and (not .Schema.IsBaseType) .Schema.IsComplexObject }}&{{ end }}{{ .Schema.GoType -}} {} - {{- else }} - {{- .Schema.Zero }} - {{- end }} - } - {{ end }} - if err := producer.Produce(rw, payload); err != nil { - panic(err) // let the recovery middleware deal with this - } - {{- if .Schema.IsComplexObject }} - } - {{- end }} - {{- end }} -} - -{{ if $.StrictResponders }} -func ({{ .ReceiverName }} *{{ pascalize .Name }}) {{ pascalize .OperationName }}Responder() {} -{{- end }} -{{ end }}// Code generated by go-swagger; DO NOT EDIT. - - -{{ if .Copyright -}}// {{ comment .Copyright -}}{{ end }} - - -package {{ .Package }} - -// This file was generated by the swagger tool. -// Editing this file might prove futile when you re-run the swagger generate command - - -import ( - "fmt" - "net/http" - - "github.com/go-openapi/errors" - "github.com/go-openapi/runtime" - "github.com/go-openapi/runtime/security" - "github.com/go-openapi/swag" - "github.com/go-openapi/validate" - "github.com/go-openapi/runtime/middleware" - - {{ imports .DefaultImports }} - {{ imports .Imports }} -) - -{{ range .Responses }} -{{ template "serverresponse" . }} -{{ end }} -{{ if .DefaultResponse }} -{{ template "serverresponse" .DefaultResponse }} -{{ end }} - -{{ if $.StrictResponders }} -type {{ pascalize .Name }}NotImplementedResponder struct { - middleware.Responder -} - -func (*{{ pascalize .Name }}NotImplementedResponder) {{ pascalize .Name }}Responder() {} - -func {{ pascalize .Name }}NotImplemented() {{ pascalize .Name }}Responder { - return &{{ pascalize .Name }}NotImplementedResponder{ - middleware.NotImplemented( - "operation authentication.{{ pascalize .Name }} has not yet been implemented", - ), - } -} - -type {{ pascalize .Name }}Responder interface { - middleware.Responder - {{ pascalize .Name }}Responder() -} -{{ end }} diff --git a/tools/swagger/templates/server/server.gotmpl b/tools/swagger/templates/server/server.gotmpl deleted file mode 100644 index 0330309..0000000 --- a/tools/swagger/templates/server/server.gotmpl +++ /dev/null @@ -1,9 +0,0 @@ -// Code generated by go-swagger; DO NOT EDIT. - - -{{ if .Copyright -}}// {{ comment .Copyright -}}{{ end }} - - -package {{ .APIPackage }} - -// this file is intentionally empty. Otherwise go-swagger will generate a server which we don't want