Seed code 17/9317/3
authorelinuxhenrik <henrik.b.andersson@est.tech>
Tue, 18 Oct 2022 14:51:52 +0000 (16:51 +0200)
committerelinuxhenrik <henrik.b.andersson@est.tech>
Wed, 19 Oct 2022 07:05:52 +0000 (09:05 +0200)
Issue-ID: NONRTRIC-805
Signed-off-by: elinuxhenrik <henrik.b.andersson@est.tech>
Change-Id: I7084fb4209cb59c05bd0c4a565bfa226121e55d6

64 files changed:
.gitignore [new file with mode: 0644]
Dockerfile [new file with mode: 0644]
README.md [new file with mode: 0644]
build-sme-ubuntu.sh [new file with mode: 0755]
container-tag.yaml [new file with mode: 0644]
generate.sh [new file with mode: 0755]
go.mod [new file with mode: 0644]
go.sum [new file with mode: 0644]
gogeneratorspecs/accesscontrolpolicyapi/generator_settings_server.yaml [new file with mode: 0644]
gogeneratorspecs/accesscontrolpolicyapi/generator_settings_types.yaml [new file with mode: 0644]
gogeneratorspecs/aefsecurityapi/generator_settings_client.yaml [new file with mode: 0644]
gogeneratorspecs/aefsecurityapi/generator_settings_server.yaml [new file with mode: 0644]
gogeneratorspecs/aefsecurityapi/generator_settings_types.yaml [new file with mode: 0644]
gogeneratorspecs/auditingapi/generator_settings_client.yaml [new file with mode: 0644]
gogeneratorspecs/auditingapi/generator_settings_server.yaml [new file with mode: 0644]
gogeneratorspecs/auditingapi/generator_settings_types.yaml [new file with mode: 0644]
gogeneratorspecs/common/generator_settings.yaml [new file with mode: 0644]
gogeneratorspecs/common29122/generator_settings.yaml [new file with mode: 0644]
gogeneratorspecs/common29571/generator_settings.yaml [new file with mode: 0644]
gogeneratorspecs/discoverserviceapi/generator_settings_client.yaml [new file with mode: 0644]
gogeneratorspecs/discoverserviceapi/generator_settings_server.yaml [new file with mode: 0644]
gogeneratorspecs/discoverserviceapi/generator_settings_types.yaml [new file with mode: 0644]
gogeneratorspecs/eventsapi/generator_settings_client.yaml [new file with mode: 0644]
gogeneratorspecs/eventsapi/generator_settings_server.yaml [new file with mode: 0644]
gogeneratorspecs/eventsapi/generator_settings_types.yaml [new file with mode: 0644]
gogeneratorspecs/invokermanagementapi/generator_settings_client.yaml [new file with mode: 0644]
gogeneratorspecs/invokermanagementapi/generator_settings_server.yaml [new file with mode: 0644]
gogeneratorspecs/invokermanagementapi/generator_settings_types.yaml [new file with mode: 0644]
gogeneratorspecs/loggingapi/generator_settings_client.yaml [new file with mode: 0644]
gogeneratorspecs/loggingapi/generator_settings_server.yaml [new file with mode: 0644]
gogeneratorspecs/loggingapi/generator_settings_types.yaml [new file with mode: 0644]
gogeneratorspecs/providermanagementapi/generator_settings_client.yaml [new file with mode: 0644]
gogeneratorspecs/providermanagementapi/generator_settings_server.yaml [new file with mode: 0644]
gogeneratorspecs/providermanagementapi/generator_settings_types.yaml [new file with mode: 0644]
gogeneratorspecs/publishserviceapi/generator_settings_client.yaml [new file with mode: 0644]
gogeneratorspecs/publishserviceapi/generator_settings_server.yaml [new file with mode: 0644]
gogeneratorspecs/publishserviceapi/generator_settings_types.yaml [new file with mode: 0644]
gogeneratorspecs/routinginfoapi/generator_settings_client.yaml [new file with mode: 0644]
gogeneratorspecs/routinginfoapi/generator_settings_server.yaml [new file with mode: 0644]
gogeneratorspecs/routinginfoapi/generator_settings_types.yaml [new file with mode: 0644]
gogeneratorspecs/securityapi/generator_settings_client.yaml [new file with mode: 0644]
gogeneratorspecs/securityapi/generator_settings_server.yaml [new file with mode: 0644]
gogeneratorspecs/securityapi/generator_settings_types.yaml [new file with mode: 0644]
internal/discoverservice/discoverservice.go [new file with mode: 0644]
internal/discoverservice/discoverservice_test.go [new file with mode: 0644]
internal/gentools/commoncollector/commoncollector.go [new file with mode: 0644]
internal/gentools/commoncollector/definitions.txt [new file with mode: 0644]
internal/gentools/enumfixer/enumfixer.go [new file with mode: 0644]
internal/gentools/specificationfixer/specificationfixer.go [new file with mode: 0644]
internal/helmmanagement/helm.go [new file with mode: 0644]
internal/helmmanagement/mocks/HelmManager.go [new file with mode: 0644]
internal/invokermanagement/invokermanagement.go [new file with mode: 0644]
internal/invokermanagement/invokermanagement_test.go [new file with mode: 0644]
internal/invokermanagement/mocks/InvokerRegister.go [new file with mode: 0644]
internal/providermanagement/mocks/ServiceRegister.go [new file with mode: 0644]
internal/providermanagement/providermanagement.go [new file with mode: 0644]
internal/providermanagement/providermanagement_test.go [new file with mode: 0644]
internal/publishservice/mocks/APIRegister.go [new file with mode: 0644]
internal/publishservice/publishservice.go [new file with mode: 0644]
internal/publishservice/publishservice_test.go [new file with mode: 0644]
internal/security/security.go [new file with mode: 0644]
internal/security/security_test.go [new file with mode: 0644]
main.go [new file with mode: 0644]
main_test.go [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..dcfc558
--- /dev/null
@@ -0,0 +1,8 @@
+.idea
+specs
+commoncollector
+enumfixer
+specificationfixer
+*.gen.go
+sme
+coverage.txt
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
new file mode 100644 (file)
index 0000000..56c939b
--- /dev/null
@@ -0,0 +1,38 @@
+#==================================================================================
+#   Copyright (C) 2022: Nordix Foundation
+#
+#   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.
+#
+#   This source code is part of the near-RT RIC (RAN Intelligent Controller)
+#   platform project (RICP).
+#==================================================================================
+
+##
+## Build
+##
+FROM nexus3.o-ran-sc.org:10001/golang:1.19.2-bullseye AS build
+WORKDIR /app
+COPY go.mod .
+COPY go.sum .
+RUN go mod download
+COPY . .
+RUN go build -o /capifcore
+##
+## Deploy
+##
+FROM gcr.io/distroless/base-debian11
+WORKDIR /
+## Copy from "build" stage
+COPY --from=build /capifcore .
+USER nonroot:nonroot
+ENTRYPOINT ["/capif"]
diff --git a/README.md b/README.md
new file mode 100644 (file)
index 0000000..8e65382
--- /dev/null
+++ b/README.md
@@ -0,0 +1,32 @@
+<!--
+ -
+   ========================LICENSE_START=================================
+   O-RAN-SC
+   %%
+   Copyright (C) 2022: Nordix Foundation
+   %%
+   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.
+   ========================LICENSE_END===================================
+
+-->
+
+# O-RAN-SC Non-RealTime CAPIF implementation
+
+This product is a Go implementation of the CAPIF Core function, based on the 3GPP CAPIF interfaces.
+
+## Run
+
+To run the Core Function run the following commands from the top of the repo:
+
+    go build
+    ./capifcore [-port <port (default 8080)>]
\ No newline at end of file
diff --git a/build-sme-ubuntu.sh b/build-sme-ubuntu.sh
new file mode 100755 (executable)
index 0000000..ace8876
--- /dev/null
@@ -0,0 +1,37 @@
+#!/bin/bash
+##############################################################################
+#
+#   Copyright (C) 2022: Nordix Foundation
+#
+#   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 -eux
+
+echo "--> build-sme-ubuntu.sh"
+# go installs tools like go-acc to $HOME/go/bin
+# ubuntu minion path lacks go
+export PATH=$PATH:/usr/local/go/bin:$HOME/go/bin
+go version
+
+# install the go coverage tool helper
+go get -v github.com/ory/go-acc
+
+export GO111MODULE=on
+go get github.com/stretchr/testify/mock@v1.7.1
+
+go-acc ./... --ignore mocks,api,common
+
+sed -i -e 's/oransc\.org\/nonrtric\/sme/sme/' coverage.txt
+
+echo "--> build-sme-ubuntu.sh ends"
diff --git a/container-tag.yaml b/container-tag.yaml
new file mode 100644 (file)
index 0000000..479af13
--- /dev/null
@@ -0,0 +1,22 @@
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2022 Nordix Foundation. All rights reserved.
+#  ========================================================================
+#  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.
+#  ============LICENSE_END=================================================
+#
+
+# The Jenkins job requires a tag to build the Docker image.
+# By default this file is in the docker build directory,
+# but the location can configured in the JJB template.
+---
+tag: 1.0.0
diff --git a/generate.sh b/generate.sh
new file mode 100755 (executable)
index 0000000..9a54322
--- /dev/null
@@ -0,0 +1,167 @@
+# -
+#   ========================LICENSE_START=================================
+#   O-RAN-SC
+#   %%
+#   Copyright (C) 2022: Nordix Foundation
+#   %%
+#   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.
+#   ========================LICENSE_END===================================
+#
+
+cwd=$(pwd)
+
+mkdir -p specs
+
+curl https://www.3gpp.org/ftp/Specs/archive/29_series/29.222/29222-h40.zip -o specs/apidef.zip
+curl https://www.3gpp.org/ftp/Specs/archive/29_series/29.122/29122-h50.zip -o specs/common29122apidef.zip
+curl https://www.3gpp.org/ftp/Specs/archive/29_series/29.508/29508-h60.zip -o specs/common29508apidef.zip
+curl https://www.3gpp.org/ftp/Specs/archive/29_series/29.510/29510-h50.zip -o specs/common29510apidef.zip
+curl https://www.3gpp.org/ftp/Specs/archive/29_series/29.512/29512-h60.zip -o specs/common29512apidef.zip
+curl https://www.3gpp.org/ftp/Specs/archive/29_series/29.514/29514-h40.zip -o specs/common29514apidef.zip
+curl https://www.3gpp.org/ftp/Specs/archive/29_series/29.517/29517-h50.zip -o specs/common29517apidef.zip
+curl https://www.3gpp.org/ftp/Specs/archive/29_series/29.518/29518-h50.zip -o specs/common29518apidef.zip
+curl https://www.3gpp.org/ftp/Specs/archive/29_series/29.522/29522-h50.zip -o specs/common29522apidef.zip
+curl https://www.3gpp.org/ftp/Specs/archive/29_series/29.523/29523-h60.zip -o specs/common29523apidef.zip
+curl https://www.3gpp.org/ftp/Specs/archive/29_series/29.554/29554-h30.zip -o specs/common29554apidef.zip
+curl https://www.3gpp.org/ftp/Specs/archive/29_series/29.571/29571-h50.zip -o specs/common29571apidef.zip
+curl https://www.3gpp.org/ftp/Specs/archive/29_series/29.572/29572-h40.zip -o specs/common29572apidef.zip
+
+cd specs/
+
+jar xvf apidef.zip
+jar xvf common29122apidef.zip
+jar xvf common29508apidef.zip
+jar xvf common29510apidef.zip
+jar xvf common29512apidef.zip
+jar xvf common29514apidef.zip
+jar xvf common29517apidef.zip
+jar xvf common29518apidef.zip
+jar xvf common29522apidef.zip
+jar xvf common29523apidef.zip
+jar xvf common29554apidef.zip
+jar xvf common29571apidef.zip
+jar xvf common29572apidef.zip
+
+sed -e 'H;x;/^\(  *\)\n\1/{s/\n.*//;x;d;}' -e 's/.*//;x;/\CivicAddress/{s/^\( *\).*/ \1/;x;d;}' TS29571_CommonData.yaml >temp.yaml
+mv temp.yaml TS29571_CommonData.yaml
+sed -e 'H;x;/^\(  *\)\n\1/{s/\n.*//;x;d;}' -e 's/.*//;x;/\GeographicArea/{s/^\( *\).*/ \1/;x;d;}' TS29571_CommonData.yaml >temp.yaml
+mv temp.yaml TS29571_CommonData.yaml
+sed '/accessTokenError.*/,+3d' TS29571_CommonData.yaml >temp.yaml
+mv temp.yaml TS29571_CommonData.yaml
+sed '/accessTokenRequest.*/,+3d' TS29571_CommonData.yaml >temp.yaml
+mv temp.yaml TS29571_CommonData.yaml
+
+sed '/oneOf.*/,+2d' TS29222_CAPIF_Publish_Service_API.yaml >temp.yaml
+mv temp.yaml TS29222_CAPIF_Publish_Service_API.yaml
+
+sed '64,68d' TS29222_CAPIF_Discover_Service_API.yaml >temp.yaml # Remove parameter preferred-aef-loc since it doesn't follow the OpenApi specification, "The behavior for nested objects and arrays is undefined."
+mv temp.yaml TS29222_CAPIF_Discover_Service_API.yaml
+
+cat TS29222_CAPIF_Security_API.yaml | sed -E 's/(    AccessTokenReq*)\:/\1:|      type: object/' | tr '|' '\n' > temp.yaml
+mv temp.yaml TS29222_CAPIF_Security_API.yaml
+
+cat TS29122_CommonData.yaml | sed 's/TS29572_Nlmf_Location/CommonData/g' > temp.yaml
+mv temp.yaml TS29122_CommonData.yaml
+cat TS29122_CommonData.yaml | sed 's/TS29554_Npcf_BDTPolicyControl/CommonData/g' > temp.yaml
+mv temp.yaml TS29122_CommonData.yaml
+cat TS29571_CommonData.yaml | sed 's/TS29571_CommonData.yaml//g' > temp.yaml
+mv temp.yaml TS29571_CommonData.yaml
+cat TS29222_CAPIF_Publish_Service_API.yaml | sed 's/TS29572_Nlmf_Location/CommonData/g' > temp.yaml
+mv temp.yaml TS29222_CAPIF_Publish_Service_API.yaml
+cat TS29222_CAPIF_Routing_Info_API.yaml | sed 's/TS29520_Nnwdaf_EventsSubscription/CommonData/g' > temp.yaml
+mv temp.yaml TS29222_CAPIF_Routing_Info_API.yaml
+cat TS29222_CAPIF_Routing_Info_API.yaml | sed 's/TS29510_Nnrf_NFManagement/CommonData/g' > temp.yaml
+mv temp.yaml TS29222_CAPIF_Routing_Info_API.yaml
+cat TS29222_CAPIF_Events_API.yaml | sed 's/TS29523_Npcf_EventExposure/CommonData/g' > temp.yaml
+mv temp.yaml TS29222_CAPIF_Events_API.yaml
+
+go install github.com/deepmap/oapi-codegen/cmd/oapi-codegen@v1.10.1
+PATH=$PATH:~/go/bin
+
+cd $cwd
+
+echo "Fixing enums"
+cd internal/gentools/enumfixer
+go build .
+./enumfixer -apidir=../../../specs
+
+cd $cwd
+echo "Gathering common references"
+cd internal/gentools/commoncollector
+go build .
+./commoncollector -apidir=../../../specs
+
+cd $cwd
+echo "Fixing misc in specifications"
+cd internal/gentools/specificationfixer
+go build .
+./specificationfixer -apidir=../../../specs
+
+cd $cwd
+
+echo "Generating TS29122_CommonData"
+mkdir -p internal/common29122
+oapi-codegen --config gogeneratorspecs/common29122/generator_settings.yaml specs/TS29122_CommonData.yaml
+echo "Generating aggregated CommonData"
+mkdir -p internal/common
+oapi-codegen --config gogeneratorspecs/common/generator_settings.yaml specs/CommonData.yaml
+echo "Generating TS29571_CommonData"
+mkdir -p internal/common29571
+oapi-codegen --config gogeneratorspecs/common29571/generator_settings.yaml specs/TS29571_CommonData.yaml
+echo "Generating TS29222_CAPIF_Publish_Service_API"
+mkdir -p internal/publishserviceapi
+oapi-codegen --config gogeneratorspecs/publishserviceapi/generator_settings_types.yaml specs/TS29222_CAPIF_Publish_Service_API.yaml
+oapi-codegen --config gogeneratorspecs/publishserviceapi/generator_settings_server.yaml specs/TS29222_CAPIF_Publish_Service_API.yaml
+echo "Generating TS29222_CAPIF_API_Invoker_Management_API"
+mkdir -p internal/invokermanagementapi
+oapi-codegen --config gogeneratorspecs/invokermanagementapi/generator_settings_types.yaml specs/TS29222_CAPIF_API_Invoker_Management_API.yaml
+oapi-codegen --config gogeneratorspecs/invokermanagementapi/generator_settings_server.yaml specs/TS29222_CAPIF_API_Invoker_Management_API.yaml
+echo "Generating TS29222_CAPIF_API_Provider_Management_API"
+mkdir -p internal/providermanagementapi
+oapi-codegen --config gogeneratorspecs/providermanagementapi/generator_settings_types.yaml specs/TS29222_CAPIF_API_Provider_Management_API.yaml
+oapi-codegen --config gogeneratorspecs/providermanagementapi/generator_settings_server.yaml specs/TS29222_CAPIF_API_Provider_Management_API.yaml
+echo "Generating TS29222_CAPIF_Discover_Service_API"
+mkdir -p internal/discoverserviceapi
+oapi-codegen --config gogeneratorspecs/discoverserviceapi/generator_settings_types.yaml specs/TS29222_CAPIF_Discover_Service_API.yaml
+oapi-codegen --config gogeneratorspecs/discoverserviceapi/generator_settings_server.yaml specs/TS29222_CAPIF_Discover_Service_API.yaml
+echo "Generating TS29222_CAPIF_Security_API"
+mkdir -p internal/securityapi
+oapi-codegen --config gogeneratorspecs/securityapi/generator_settings_types.yaml specs/TS29222_CAPIF_Security_API.yaml
+oapi-codegen --config gogeneratorspecs/securityapi/generator_settings_server.yaml specs/TS29222_CAPIF_Security_API.yaml
+echo "Generating TS29222_CAPIF_Logging_API_Invocation_API"
+mkdir -p internal/loggingapi
+oapi-codegen --config gogeneratorspecs/loggingapi/generator_settings_types.yaml specs/TS29222_CAPIF_Logging_API_Invocation_API.yaml
+oapi-codegen --config gogeneratorspecs/loggingapi/generator_settings_server.yaml specs/TS29222_CAPIF_Logging_API_Invocation_API.yaml
+echo "Generating TS29222_CAPIF_Routing_Info_API"
+mkdir -p internal/routinginfoapi
+oapi-codegen --config gogeneratorspecs/routinginfoapi/generator_settings_types.yaml specs/TS29222_CAPIF_Routing_Info_API.yaml
+oapi-codegen --config gogeneratorspecs/routinginfoapi/generator_settings_server.yaml specs/TS29222_CAPIF_Routing_Info_API.yaml
+echo "Generating TS29222_CAPIF_Access_Control_Policy_API"
+mkdir -p internal/accesscontrolpolicyapi
+oapi-codegen --config gogeneratorspecs/accesscontrolpolicyapi/generator_settings_types.yaml specs/TS29222_CAPIF_Access_Control_Policy_API.yaml
+oapi-codegen --config gogeneratorspecs/accesscontrolpolicyapi/generator_settings_server.yaml specs/TS29222_CAPIF_Access_Control_Policy_API.yaml
+echo "Generating TS29222_CAPIF_Events_API"
+mkdir -p internal/eventsapi
+oapi-codegen --config gogeneratorspecs/eventsapi/generator_settings_types.yaml specs/TS29222_CAPIF_Events_API.yaml
+oapi-codegen --config gogeneratorspecs/eventsapi/generator_settings_server.yaml specs/TS29222_CAPIF_Events_API.yaml
+echo "Generating TS29222_CAPIF_Auditing_API"
+mkdir -p internal/auditingapi
+oapi-codegen --config gogeneratorspecs/auditingapi/generator_settings_types.yaml specs/TS29222_CAPIF_Auditing_API.yaml
+oapi-codegen --config gogeneratorspecs/auditingapi/generator_settings_server.yaml specs/TS29222_CAPIF_Auditing_API.yaml
+echo "Generating TS29222_AEF_Security_API"
+mkdir -p internal/aefsecurityapi
+oapi-codegen --config gogeneratorspecs/aefsecurityapi/generator_settings_types.yaml specs/TS29222_AEF_Security_API.yaml
+oapi-codegen --config gogeneratorspecs/aefsecurityapi/generator_settings_server.yaml specs/TS29222_AEF_Security_API.yaml
+
+echo "Cleanup"
+rm -rf specs
diff --git a/go.mod b/go.mod
new file mode 100644 (file)
index 0000000..cc2573a
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,160 @@
+module oransc.org/nonrtric/sme
+
+go 1.19
+
+require (
+       github.com/deepmap/oapi-codegen v1.11.0
+       github.com/getkin/kin-openapi v0.106.0
+       github.com/labstack/echo/v4 v4.9.1
+       github.com/pkg/errors v0.9.1
+       github.com/sirupsen/logrus v1.9.0
+       github.com/stretchr/testify v1.7.1
+       gopkg.in/yaml.v2 v2.4.0
+       helm.sh/helm/v3 v3.9.0
+       k8s.io/cli-runtime v0.25.3-rc.0
+       k8s.io/client-go v0.25.3-rc.0
+)
+
+require (
+       github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
+       github.com/BurntSushi/toml v1.1.0 // indirect
+       github.com/MakeNowJust/heredoc v1.0.0 // indirect
+       github.com/Masterminds/goutils v1.1.1 // indirect
+       github.com/Masterminds/semver/v3 v3.1.1 // indirect
+       github.com/Masterminds/sprig/v3 v3.2.2 // indirect
+       github.com/Masterminds/squirrel v1.5.3 // indirect
+       github.com/PuerkitoBio/purell v1.1.1 // indirect
+       github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
+       github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 // indirect
+       github.com/beorn7/perks v1.0.1 // indirect
+       github.com/cespare/xxhash v1.1.0 // indirect
+       github.com/cespare/xxhash/v2 v2.1.2 // indirect
+       github.com/chai2010/gettext-go v1.0.2 // indirect
+       github.com/containerd/containerd v1.6.6 // indirect
+       github.com/cyphar/filepath-securejoin v0.2.3 // indirect
+       github.com/davecgh/go-spew v1.1.1 // indirect
+       github.com/dgraph-io/ristretto v0.0.2 // indirect
+       github.com/docker/cli v20.10.17+incompatible // indirect
+       github.com/docker/distribution v2.8.1+incompatible // indirect
+       github.com/docker/docker v20.10.17+incompatible // indirect
+       github.com/docker/docker-credential-helpers v0.6.4 // indirect
+       github.com/docker/go-connections v0.4.0 // indirect
+       github.com/docker/go-metrics v0.0.1 // indirect
+       github.com/docker/go-units v0.4.0 // indirect
+       github.com/emicklei/go-restful/v3 v3.8.0 // indirect
+       github.com/evanphx/json-patch v5.6.0+incompatible // indirect
+       github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect
+       github.com/fatih/color v1.13.0 // indirect
+       github.com/fsnotify/fsnotify v1.4.9 // indirect
+       github.com/go-errors/errors v1.0.1 // indirect
+       github.com/go-gorp/gorp/v3 v3.0.2 // indirect
+       github.com/go-logr/logr v1.2.3 // indirect
+       github.com/go-openapi/jsonpointer v0.19.5 // indirect
+       github.com/go-openapi/jsonreference v0.19.5 // indirect
+       github.com/go-openapi/swag v0.21.1 // indirect
+       github.com/gobwas/glob v0.2.3 // indirect
+       github.com/gogo/protobuf v1.3.2 // indirect
+       github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
+       github.com/golang/protobuf v1.5.2 // indirect
+       github.com/google/btree v1.0.1 // indirect
+       github.com/google/gnostic v0.5.7-v3refs // indirect
+       github.com/google/go-cmp v0.5.8 // indirect
+       github.com/google/gofuzz v1.2.0 // indirect
+       github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
+       github.com/google/uuid v1.3.0 // indirect
+       github.com/gorilla/mux v1.8.0 // indirect
+       github.com/gosuri/uitable v0.0.4 // indirect
+       github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect
+       github.com/hashicorp/hcl v1.0.0 // indirect
+       github.com/huandu/xstrings v1.3.2 // indirect
+       github.com/imdario/mergo v0.3.12 // indirect
+       github.com/inconshreveable/mousetrap v1.0.0 // indirect
+       github.com/invopop/yaml v0.1.0 // indirect
+       github.com/jmoiron/sqlx v1.3.5 // indirect
+       github.com/josharian/intern v1.0.0 // indirect
+       github.com/json-iterator/go v1.1.12 // indirect
+       github.com/klauspost/compress v1.13.6 // indirect
+       github.com/labstack/gommon v0.4.0 // indirect
+       github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect
+       github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
+       github.com/lib/pq v1.10.6 // indirect
+       github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
+       github.com/magiconair/properties v1.8.5 // indirect
+       github.com/mailru/easyjson v0.7.7 // indirect
+       github.com/mattn/go-colorable v0.1.12 // indirect
+       github.com/mattn/go-isatty v0.0.14 // indirect
+       github.com/mattn/go-runewidth v0.0.9 // indirect
+       github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
+       github.com/mitchellh/copystructure v1.2.0 // indirect
+       github.com/mitchellh/go-wordwrap v1.0.0 // indirect
+       github.com/mitchellh/mapstructure v1.4.1 // indirect
+       github.com/mitchellh/reflectwalk v1.0.2 // indirect
+       github.com/moby/locker v1.0.1 // indirect
+       github.com/moby/spdystream v0.2.0 // indirect
+       github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect
+       github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
+       github.com/modern-go/reflect2 v1.0.2 // indirect
+       github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
+       github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
+       github.com/morikuni/aec v1.0.0 // indirect
+       github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
+       github.com/opencontainers/go-digest v1.0.0 // indirect
+       github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 // indirect
+       github.com/ory/go-acc v0.2.8 // indirect
+       github.com/ory/viper v1.7.5 // indirect
+       github.com/pborman/uuid v1.2.0 // indirect
+       github.com/pelletier/go-toml v1.9.3 // indirect
+       github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
+       github.com/pmezard/go-difflib v1.0.0 // indirect
+       github.com/prometheus/client_golang v1.12.1 // indirect
+       github.com/prometheus/client_model v0.2.0 // indirect
+       github.com/prometheus/common v0.32.1 // indirect
+       github.com/prometheus/procfs v0.7.3 // indirect
+       github.com/rubenv/sql-migrate v1.1.2 // indirect
+       github.com/russross/blackfriday v1.5.2 // indirect
+       github.com/shopspring/decimal v1.2.0 // indirect
+       github.com/spf13/afero v1.6.0 // indirect
+       github.com/spf13/cast v1.4.1 // indirect
+       github.com/spf13/cobra v1.5.0 // indirect
+       github.com/spf13/jwalterweatherman v1.1.0 // indirect
+       github.com/spf13/pflag v1.0.5 // indirect
+       github.com/stretchr/objx v0.4.0 // indirect
+       github.com/subosito/gotenv v1.2.0 // indirect
+       github.com/valyala/bytebufferpool v1.0.0 // indirect
+       github.com/valyala/fasttemplate v1.2.1 // indirect
+       github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect
+       github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
+       github.com/xeipuuv/gojsonschema v1.2.0 // indirect
+       github.com/xlab/treeprint v1.1.0 // indirect
+       go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect
+       golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect
+       golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect
+       golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect
+       golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect
+       golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect
+       golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
+       golang.org/x/text v0.3.7 // indirect
+       golang.org/x/time v0.0.0-20220411224347-583f2d630306 // indirect
+       google.golang.org/appengine v1.6.7 // indirect
+       google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21 // indirect
+       google.golang.org/grpc v1.47.0 // indirect
+       google.golang.org/protobuf v1.28.0 // indirect
+       gopkg.in/inf.v0 v0.9.1 // indirect
+       gopkg.in/ini.v1 v1.62.0 // indirect
+       gopkg.in/yaml.v3 v3.0.1 // indirect
+       k8s.io/api v0.25.3-rc.0 // indirect
+       k8s.io/apiextensions-apiserver v0.25.2 // indirect
+       k8s.io/apimachinery v0.25.3-rc.0 // indirect
+       k8s.io/apiserver v0.25.2 // indirect
+       k8s.io/component-base v0.25.2 // indirect
+       k8s.io/klog/v2 v2.70.1 // indirect
+       k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1 // indirect
+       k8s.io/kubectl v0.25.2 // indirect
+       k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed // indirect
+       oras.land/oras-go v1.1.1 // indirect
+       sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
+       sigs.k8s.io/kustomize/api v0.12.1 // indirect
+       sigs.k8s.io/kustomize/kyaml v0.13.9 // indirect
+       sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
+       sigs.k8s.io/yaml v1.3.0 // indirect
+)
diff --git a/go.sum b/go.sum
new file mode 100644 (file)
index 0000000..c43e7bc
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,1172 @@
+cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
+cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
+cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
+cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
+cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
+cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
+cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
+cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
+cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
+cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
+cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
+cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
+cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
+cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
+cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
+cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=
+cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
+cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
+cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
+cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
+cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
+cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
+cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
+cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
+cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
+cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
+cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
+cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
+cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
+cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
+cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
+cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
+cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
+cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
+cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
+cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
+dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
+github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
+github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/BurntSushi/toml v1.1.0 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I=
+github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
+github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
+github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
+github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ=
+github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE=
+github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
+github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
+github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
+github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
+github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
+github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
+github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
+github.com/Masterminds/sprig/v3 v3.2.2 h1:17jRggJu518dr3QaafizSXOjKYp94wKfABxUmyxvxX8=
+github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk=
+github.com/Masterminds/squirrel v1.5.3 h1:YPpoceAcxuzIljlr5iWpNKaql7hLeG1KLSrhvdHpkZc=
+github.com/Masterminds/squirrel v1.5.3/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10=
+github.com/Microsoft/go-winio v0.5.1 h1:aPJp2QD7OOrhO5tQXqQoGSJc+DjDtWTGLOmNyAm6FgY=
+github.com/Microsoft/hcsshim v0.9.3 h1:k371PzBuRrz2b+ebGuI2nVgVhgsVX60jMfSw80NECxo=
+github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
+github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
+github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
+github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
+github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
+github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs=
+github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
+github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
+github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
+github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
+github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
+github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
+github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
+github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
+github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
+github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
+github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
+github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 h1:4daAzAu0S6Vi7/lbWECcX0j45yZReDZ56BQsrVBOEEY=
+github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=
+github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
+github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
+github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
+github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
+github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
+github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM=
+github.com/bshuster-repo/logrus-logstash-hook v1.0.0 h1:e+C0SB5R1pu//O4MQ3f9cFuPGoOVeF2fE4Og9otCc70=
+github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd h1:rFt+Y/IK1aEZkEHchZRSq9OQbsSzIT/OrI8YFFmRIng=
+github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b h1:otBG+dV+YK+Soembjv71DPz3uX/V/6MMlSyD9JBQ6kQ=
+github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 h1:nvj0OLI3YqYXer/kZD8Ri1aaunCxIEsOst1BVJswV0o=
+github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
+github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
+github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
+github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
+github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk=
+github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA=
+github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
+github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
+github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
+github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
+github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
+github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
+github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
+github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
+github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
+github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
+github.com/containerd/cgroups v1.0.3 h1:ADZftAkglvCiD44c77s5YmMqaP2pzVCFZvBmAlBdAP4=
+github.com/containerd/containerd v1.6.6 h1:xJNPhbrmz8xAMDNoVjHy9YHtWwEQNS+CDkcIRh7t8Y0=
+github.com/containerd/containerd v1.6.6/go.mod h1:ZoP1geJldzCVY3Tonoz7b1IXk8rIX0Nltt5QE4OMNk0=
+github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
+github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
+github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
+github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
+github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
+github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
+github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
+github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
+github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
+github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
+github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
+github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
+github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4=
+github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI=
+github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
+github.com/danieljoos/wincred v1.1.0/go.mod h1:XYlo+eRTsVA9aHGp7NGjFkPla4m+DCL7hqDjlFjiygg=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc=
+github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.0-20210816181553-5444fa50b93d/go.mod h1:tmAIfUFEirG/Y8jhZ9M+h36obRZAk/1fcSpXwAVlfqE=
+github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs=
+github.com/deepmap/oapi-codegen v1.11.0 h1:f/X2NdIkaBKsSdpeuwLnY/vDI0AtPUrmB5LMgc7YD+A=
+github.com/deepmap/oapi-codegen v1.11.0/go.mod h1:k+ujhoQGxmQYBZBbxhOZNZf4j08qv5mC+OH+fFTnKxM=
+github.com/denisenkom/go-mssqldb v0.9.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
+github.com/dgraph-io/ristretto v0.0.1/go.mod h1:T40EBc7CJke8TkpiYfGGKAeFjSaxuFXhuXRyumBd6RE=
+github.com/dgraph-io/ristretto v0.0.2 h1:a5WaUrDa0qm0YrAAS1tUykT5El3kt62KNZZeMxQn3po=
+github.com/dgraph-io/ristretto v0.0.2/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
+github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
+github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
+github.com/distribution/distribution/v3 v3.0.0-20211118083504-a29a3c99a684 h1:DBZ2sN7CK6dgvHVpQsQj4sRMCbWTmd17l+5SUCjnQSY=
+github.com/docker/cli v20.10.17+incompatible h1:eO2KS7ZFeov5UJeaDmIs1NFEDRf32PaqRpvoEkKBy5M=
+github.com/docker/cli v20.10.17+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
+github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68=
+github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
+github.com/docker/docker v20.10.17+incompatible h1:JYCuMrWaVNophQTOrMMoSwudOVEfcegoZZrleKc1xwE=
+github.com/docker/docker v20.10.17+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
+github.com/docker/docker-credential-helpers v0.6.4 h1:axCks+yV+2MR3/kZhAmy07yC56WZ2Pwu/fKWtKuZB0o=
+github.com/docker/docker-credential-helpers v0.6.4/go.mod h1:ofX3UI0Gz1TteYBjtgs07O36Pyasyp66D2uKT7H8W1c=
+github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
+github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
+github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8=
+github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8=
+github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw=
+github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
+github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
+github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1 h1:ZClxb8laGDf5arXfYcAtECDFgAgHklGI8CxgjHnXKJ4=
+github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
+github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153 h1:yUdfgN0XgIJw7foRItutHYUIhlcKzcSf5vDpdhQAKTc=
+github.com/emicklei/go-restful/v3 v3.8.0 h1:eCZ8ulSerjdAiaNpF7GxXIE7ZCMo1moN1qX+S609eVw=
+github.com/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
+github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
+github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
+github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
+github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
+github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
+github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
+github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
+github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
+github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U=
+github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
+github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM=
+github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4=
+github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
+github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
+github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
+github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ=
+github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
+github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
+github.com/getkin/kin-openapi v0.94.0/go.mod h1:LWZfzOd7PRy8GJ1dJ6mCU6tNdSfOwRac1BUPam4aw6Q=
+github.com/getkin/kin-openapi v0.106.0 h1:hrqfqJPAvWvuO/V0lCr/xyQOq4Gy21mcr28JJOSRcEI=
+github.com/getkin/kin-openapi v0.106.0/go.mod h1:9Dhr+FasATJZjS4iOLvB0hkaxgYdulrNYm2e9epLWOo=
+github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
+github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
+github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U=
+github.com/go-chi/chi/v5 v5.0.7/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
+github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=
+github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
+github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
+github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
+github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
+github.com/go-gorp/gorp/v3 v3.0.2 h1:ULqJXIekoqMx29FI5ekXXFoH1dT2Vc8UhnRzBg+Emz4=
+github.com/go-gorp/gorp/v3 v3.0.2/go.mod h1:BJ3q1ejpV8cVALtcXvXaXyTOlMmJhWDxTmncaR6rwBY=
+github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
+github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
+github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
+github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
+github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
+github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
+github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
+github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
+github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
+github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
+github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
+github.com/go-openapi/jsonreference v0.19.5 h1:1WJP/wi4OjB4iV8KVbH73rQaoialJrqv8gitZLxGLtM=
+github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg=
+github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
+github.com/go-openapi/swag v0.21.1 h1:wm0rhTb5z7qpJRHBdPOMuY4QjVUMbF6/kwoYeRAOrKU=
+github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
+github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
+github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
+github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
+github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
+github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
+github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
+github.com/go-playground/validator/v10 v10.11.0/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU=
+github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
+github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
+github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
+github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
+github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
+github.com/gobuffalo/logger v1.0.6 h1:nnZNpxYo0zx+Aj9RfMPBm+x9zAU2OayFh/xrAWi34HU=
+github.com/gobuffalo/logger v1.0.6/go.mod h1:J31TBEHR1QLV2683OXTAItYIg8pv2JMHnF/quuAbMjs=
+github.com/gobuffalo/packd v1.0.1 h1:U2wXfRr4E9DH8IdsDLlRFwTZTK7hLfq9qT/QHXGVe/0=
+github.com/gobuffalo/packd v1.0.1/go.mod h1:PP2POP3p3RXGz7Jh6eYEf93S7vA2za6xM7QT85L4+VY=
+github.com/gobuffalo/packr/v2 v2.8.3 h1:xE1yzvnO56cUC0sTpKR3DIbxZgB54AftTFMhB2XEWlY=
+github.com/gobuffalo/packr/v2 v2.8.3/go.mod h1:0SahksCVcx4IMnigTjiFuyldmTrdTctXsOdiU5KwbKc=
+github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
+github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
+github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
+github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
+github.com/godror/godror v0.24.2/go.mod h1:wZv/9vPiUib6tkoDl+AZ/QLf5YZgMravZ7jxH2eQWAE=
+github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
+github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
+github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
+github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
+github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
+github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
+github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
+github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
+github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
+github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
+github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
+github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
+github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
+github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
+github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
+github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
+github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
+github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
+github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
+github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
+github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
+github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
+github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
+github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
+github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
+github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
+github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
+github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
+github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y=
+github.com/gomodule/redigo v1.8.2 h1:H5XSIre1MB5NbPYFp+i1NBbb5qN1W8Y8YAQoAYbkm8k=
+github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
+github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
+github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
+github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
+github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54=
+github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ=
+github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
+github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
+github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
+github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
+github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
+github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
+github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
+github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
+github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
+github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
+github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
+github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
+github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
+github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
+github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4=
+github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
+github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
+github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
+github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
+github.com/gosuri/uitable v0.0.4 h1:IG2xLKRvErL3uhY6e1BylFzG+aJiwQviDDTfOKeKTpY=
+github.com/gosuri/uitable v0.0.4/go.mod h1:tKR86bXuXPZazfOTG1FIzvjIdXzd0mo4Vtn16vt0PJo=
+github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM=
+github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
+github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
+github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
+github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
+github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
+github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
+github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
+github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
+github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
+github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
+github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
+github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
+github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
+github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
+github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
+github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
+github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
+github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
+github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
+github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
+github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
+github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
+github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
+github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
+github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
+github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
+github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
+github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw=
+github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
+github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
+github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
+github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
+github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
+github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
+github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
+github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
+github.com/invopop/yaml v0.1.0 h1:YW3WGUoJEXYfzWBjn00zIlrw7brGVD0fUKRYDPAPhrc=
+github.com/invopop/yaml v0.1.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q=
+github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g=
+github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ=
+github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
+github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
+github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
+github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
+github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
+github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
+github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
+github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
+github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
+github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
+github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
+github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
+github.com/karrick/godirwalk v1.16.1 h1:DynhcF+bztK8gooS0+NDJFrdNZjJ3gzVzC545UNA9iw=
+github.com/karrick/godirwalk v1.16.1/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk=
+github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
+github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
+github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
+github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
+github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/kortschak/utter v1.0.1/go.mod h1:vSmSjbyrlKjjsL71193LmzBOKgwePk9DH6uFaWHIInc=
+github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
+github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
+github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
+github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
+github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
+github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+github.com/labstack/echo/v4 v4.7.2/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20Ltm0OvSks=
+github.com/labstack/echo/v4 v4.9.1 h1:GliPYSpzGKlyOhqIbG8nmHBo3i1saKWFOgh41AN3b+Y=
+github.com/labstack/echo/v4 v4.9.1/go.mod h1:Pop5HLc+xoc4qhTZ1ip6C0RtP7Z+4VzRLWZZFKqbbjo=
+github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
+github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8=
+github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
+github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 h1:SOEGU9fKiNWd/HOJuq6+3iTQz8KNCLtVX6idSoTLdUw=
+github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o=
+github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 h1:P6pPBnrTSX3DEVR4fDembhRWSsG5rVo6hYhAB/ADZrk=
+github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw=
+github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
+github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
+github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y=
+github.com/lestrrat-go/blackmagic v1.0.0/go.mod h1:TNgH//0vYSs8VXDCfkZLgIrVTTXQELZffUV0tz3MtdQ=
+github.com/lestrrat-go/blackmagic v1.0.1/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU=
+github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E=
+github.com/lestrrat-go/iter v1.0.1/go.mod h1:zIdgO1mRKhn8l9vrZJZz9TUMMFbQbLeTsbqPDrJ/OJc=
+github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4=
+github.com/lestrrat-go/jwx v1.2.24/go.mod h1:zoNuZymNl5lgdcu6P7K6ie2QRll5HVfF4xwxBBK1NxY=
+github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I=
+github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/lib/pq v1.10.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
+github.com/lib/pq v1.10.6 h1:jbk+ZieJ0D7EVGJYpL9QTz7/YW6UHbmdnZWYyK5cdBs=
+github.com/lib/pq v1.10.6/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
+github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0=
+github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE=
+github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
+github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
+github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls=
+github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
+github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
+github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
+github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
+github.com/markbates/errx v1.1.0 h1:QDFeR+UP95dO12JgW+tgi2UVfo0V8YBHiUIOaeBPiEI=
+github.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHhA0wswc=
+github.com/markbates/oncer v1.0.0 h1:E83IaVAHygyndzPimgUYJjbshhDTALZyXxvk9FOlQRY=
+github.com/markbates/oncer v1.0.0/go.mod h1:Z59JA581E9GP6w96jai+TGqafHPW+cPfRxz2aSZ0mcI=
+github.com/markbates/safe v1.0.1 h1:yjZkbvRM6IzKj9tlu/zMJLS0n/V351OZWRnF3QfaUxI=
+github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
+github.com/matryer/moq v0.2.7/go.mod h1:kITsx543GOENm48TUAQyJ9+SAvFSr7iGQXPoth/VUBk=
+github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
+github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
+github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
+github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
+github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
+github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
+github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
+github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
+github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
+github.com/mattn/go-oci8 v0.1.1/go.mod h1:wjDx6Xm9q7dFtHJvIlrI99JytznLw5wQ4R+9mNXJwGI=
+github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
+github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
+github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
+github.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg=
+github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
+github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
+github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI=
+github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
+github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
+github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
+github.com/mitchellh/cli v1.1.2/go.mod h1:6iaV0fGdElS6dPBx0EApTxHrcWvmJphyh2n8YBLPPZ4=
+github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
+github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
+github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
+github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
+github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
+github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
+github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4=
+github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
+github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
+github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
+github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
+github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
+github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag=
+github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
+github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
+github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
+github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=
+github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=
+github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8=
+github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
+github.com/moby/sys/mountinfo v0.5.0 h1:2Ks8/r6lopsxWi9m58nlwjaeSzUX9iiL1vj5qB/9ObI=
+github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 h1:dcztxKSvZ4Id8iPpHERQBbIJfabdt4wUm5qy3wOL2Zc=
+github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw=
+github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
+github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
+github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
+github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
+github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
+github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
+github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0=
+github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4=
+github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
+github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
+github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
+github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
+github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
+github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
+github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
+github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
+github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
+github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
+github.com/onsi/ginkgo/v2 v2.1.6 h1:Fx2POJZfKRQcM1pH49qSZiYeu319wji004qX+GDovrU=
+github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q=
+github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
+github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
+github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 h1:rc3tiVYb5z54aKaDfakKn0dDjIyPpTtszkjuMzyt7ec=
+github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
+github.com/ory/go-acc v0.2.8 h1:rOHHAPQjf0u7eHFGWpiXK+gIu/e0GRSJNr9pDukdNC4=
+github.com/ory/go-acc v0.2.8/go.mod h1:iCRZUdGb/7nqvSn8xWZkhfVrtXRZ9Wru2E5rabCjFPI=
+github.com/ory/viper v1.7.5 h1:+xVdq7SU3e1vNaCsk/ixsfxE4zylk1TJUiJrY647jUE=
+github.com/ory/viper v1.7.5/go.mod h1:ypOuyJmEUb3oENywQZRgeAMwqgOyDqwboO1tj3DjTaM=
+github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
+github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g=
+github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
+github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
+github.com/pelletier/go-toml v1.8.0/go.mod h1:D6yutnOGMveHEPV7VQOuvI/gXY61bv+9bAOTRnLElKs=
+github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ=
+github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
+github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
+github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
+github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 h1:JhzVVoYvbOACxoUmOs6V/G4D5nPVUW73rKvXxP4XUJc=
+github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
+github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
+github.com/poy/onpar v0.0.0-20190519213022-ee068f8ea4d1 h1:oL4IBbcqwhhNWh31bjOX8C/OCy0zs9906d/VUru+bqg=
+github.com/poy/onpar v0.0.0-20190519213022-ee068f8ea4d1/go.mod h1:nSbFQvMj97ZyhFRSJYtut+msi4sOY6zJDGCdSc+/rZU=
+github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
+github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
+github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
+github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
+github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
+github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
+github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk=
+github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
+github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
+github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
+github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
+github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
+github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
+github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
+github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
+github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
+github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4=
+github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
+github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
+github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
+github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
+github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
+github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
+github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
+github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU=
+github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
+github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
+github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
+github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
+github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
+github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
+github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
+github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
+github.com/rubenv/sql-migrate v1.1.2 h1:9M6oj4e//owVVHYrFISmY9LBRw6gzkCNmD9MV36tZeQ=
+github.com/rubenv/sql-migrate v1.1.2/go.mod h1:/7TZymwxN8VWumcIxw1jjHEcR1djpdkMHQPT4FWdnbQ=
+github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
+github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
+github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
+github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
+github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
+github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
+github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
+github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
+github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
+github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
+github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
+github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
+github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
+github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
+github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
+github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
+github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
+github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
+github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
+github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
+github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
+github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY=
+github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
+github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
+github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
+github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA=
+github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
+github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
+github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk=
+github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU=
+github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM=
+github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
+github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
+github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
+github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
+github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
+github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
+github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns=
+github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
+github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
+github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
+github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
+github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
+github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
+github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
+github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
+github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
+github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
+github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
+github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4=
+github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
+github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
+github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
+github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
+github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
+github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
+github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
+github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
+github.com/xlab/treeprint v1.1.0 h1:G/1DjNkPpfZCFt9CSh6b5/nY4VimlbHF3Rh4obvtzDk=
+github.com/xlab/treeprint v1.1.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0=
+github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
+github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
+github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
+github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
+github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43 h1:+lm10QQTNSBd8DVTNGHx7o/IKu9HYDvLMffDhbyLccI=
+github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50 h1:hlE8//ciYMztlGpl/VA+Zm1AcTPHYkHJPbHqE6WJUXE=
+github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f h1:ERexzlUfuTvpE74urLSbIQW0Z/6hF9t8U4NsJLaioAY=
+github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs=
+github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
+go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
+go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
+go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
+go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
+go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
+go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
+go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
+go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
+go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
+go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
+go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M=
+go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
+go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
+go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 h1:+FNtrFTmVw0YZGpBGX56XDee331t6JAXeK2bcyhLOOc=
+go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o=
+go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
+go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
+go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
+go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
+go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
+go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
+golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/crypto v0.0.0-20220427172511-eb4f295cb31f/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/crypto v0.0.0-20220513210258-46612604a0f9/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM=
+golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
+golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
+golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
+golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
+golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
+golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
+golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
+golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
+golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
+golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
+golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
+golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
+golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
+golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
+golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
+golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
+golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
+golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
+golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
+golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
+golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
+golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
+golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
+golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20220513224357-95641704303c/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg=
+golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220513210249-45d2b4557a2a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20220411224347-583f2d630306 h1:+gHMid33q6pen7kv9xvT+JRinntgeXO2AeZVd0AWD3w=
+golang.org/x/time v0.0.0-20220411224347-583f2d630306/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
+golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
+golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
+golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
+golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
+golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
+golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
+golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
+golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
+google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
+google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
+google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
+google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
+google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
+google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
+google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
+google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
+google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
+google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
+google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
+google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
+google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
+google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
+google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
+google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8=
+google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
+google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
+google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
+google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
+google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
+google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
+google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
+google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
+google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
+google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
+google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
+google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
+google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
+google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
+google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
+google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21 h1:hrbNEivu7Zn1pxvHk6MBrq9iE22woVILTHqexqBxe6I=
+google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
+google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
+google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
+google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
+google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
+google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
+google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
+google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
+google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
+google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
+google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
+google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
+google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
+google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
+google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
+google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
+google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
+google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
+google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
+google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
+google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
+google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
+google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
+google.golang.org/grpc v1.47.0 h1:9n77onPX5F3qfFCqjy9dhn8PbNQsIKeVU04J9G7umt8=
+google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
+google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
+google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
+google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
+google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
+google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
+google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
+google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
+google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
+google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
+google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
+google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
+google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
+gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
+gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
+gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
+gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
+gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
+gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
+gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
+gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
+gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=
+helm.sh/helm/v3 v3.9.0 h1:qDSWViuF6SzZX5s5AB/NVRGWmdao7T5j4S4ebIkMGag=
+helm.sh/helm/v3 v3.9.0/go.mod h1:fzZfyslcPAWwSdkXrXlpKexFeE2Dei8N27FFQWt+PN0=
+honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
+honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
+honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
+k8s.io/api v0.25.3-rc.0 h1:abmQ96RwK/xVgFrDxIkxdCoQ4qr7Uh+sPfjIpecpJIg=
+k8s.io/api v0.25.3-rc.0/go.mod h1:KTkuGVHV7vKlkf1FHDtbF687n22h3pQ6ovWs/Eobm78=
+k8s.io/apiextensions-apiserver v0.25.2 h1:8uOQX17RE7XL02ngtnh3TgifY7EhekpK+/piwzQNnBo=
+k8s.io/apiextensions-apiserver v0.25.2/go.mod h1:iRwwRDlWPfaHhuBfQ0WMa5skdQfrE18QXJaJvIDLvE8=
+k8s.io/apimachinery v0.25.3-rc.0 h1:nhztVhLsZuw2xENfIrVXcsNUiemnlH/r+Bb8hbl/1gA=
+k8s.io/apimachinery v0.25.3-rc.0/go.mod h1:hqqA1X0bsgsxI6dXsJ4HnNTBOmJNxyPp8dw3u2fSHwA=
+k8s.io/apiserver v0.25.2 h1:YePimobk187IMIdnmsMxsfIbC5p4eX3WSOrS9x6FEYw=
+k8s.io/apiserver v0.25.2/go.mod h1:30r7xyQTREWCkG2uSjgjhQcKVvAAlqoD+YyrqR6Cn+I=
+k8s.io/cli-runtime v0.25.3-rc.0 h1:hTBm1tPNY4uXfpbeOZjT18AlzaEIN0CgfB6rz1XLuKA=
+k8s.io/cli-runtime v0.25.3-rc.0/go.mod h1:o3qnMjKIbAT8hrc5gByX+Pi3As4bqVxDtr6bkysAhWw=
+k8s.io/client-go v0.25.3-rc.0 h1:RDSXTIbzXU8jB1dElqSiF1nyMhiZgEzqVeGA874Hkm4=
+k8s.io/client-go v0.25.3-rc.0/go.mod h1:qkx9IzH1FM7r01F4vWZEYHXTPZadHtJpmzZQZyrrWdM=
+k8s.io/component-base v0.25.2 h1:Nve/ZyHLUBHz1rqwkjXm/Re6IniNa5k7KgzxZpTfSQY=
+k8s.io/component-base v0.25.2/go.mod h1:90W21YMr+Yjg7MX+DohmZLzjsBtaxQDDwaX4YxDkl60=
+k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
+k8s.io/klog/v2 v2.70.1 h1:7aaoSdahviPmR+XkS7FyxlkkXs6tHISSG03RxleQAVQ=
+k8s.io/klog/v2 v2.70.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
+k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1 h1:MQ8BAZPZlWk3S9K4a9NCkIFQtZShWqoha7snGixVgEA=
+k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1/go.mod h1:C/N6wCaBHeBHkHUesQOQy2/MZqGgMAFPqGsGQLdbZBU=
+k8s.io/kubectl v0.25.2 h1:2993lTeVimxKSWx/7z2PiJxUILygRa3tmC4QhFaeioA=
+k8s.io/kubectl v0.25.2/go.mod h1:eoBGJtKUj7x38KXelz+dqVtbtbKwCqyKzJWmBHU0prg=
+k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed h1:jAne/RjBTyawwAy0utX5eqigAwz/lQhTmy+Hr/Cpue4=
+k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
+oras.land/oras-go v1.1.1 h1:gI00ftziRivKXaw1BdMeEoIA4uBgga33iVlOsEwefFs=
+oras.land/oras-go v1.1.1/go.mod h1:n2TE1ummt9MUyprGhT+Q7kGZUF4kVUpYysPFxeV2IpQ=
+rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
+rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
+rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
+sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
+sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
+sigs.k8s.io/kustomize/api v0.12.1 h1:7YM7gW3kYBwtKvoY216ZzY+8hM+lV53LUayghNRJ0vM=
+sigs.k8s.io/kustomize/api v0.12.1/go.mod h1:y3JUhimkZkR6sbLNwfJHxvo1TCLwuwm14sCYnkH6S1s=
+sigs.k8s.io/kustomize/kyaml v0.13.9 h1:Qz53EAaFFANyNgyOEJbT/yoIHygK40/ZcvU3rgry2Tk=
+sigs.k8s.io/kustomize/kyaml v0.13.9/go.mod h1:QsRbD0/KcU+wdk0/L0fIp2KLnohkVzs6fQ85/nOXac4=
+sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE=
+sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E=
+sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
+sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
diff --git a/gogeneratorspecs/accesscontrolpolicyapi/generator_settings_server.yaml b/gogeneratorspecs/accesscontrolpolicyapi/generator_settings_server.yaml
new file mode 100644 (file)
index 0000000..43c0a7e
--- /dev/null
@@ -0,0 +1,28 @@
+# -
+#   ========================LICENSE_START=================================
+#   O-RAN-SC
+#   %%
+#   Copyright (C) 2022: Nordix Foundation
+#   %%
+#   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.
+#   ========================LICENSE_END===================================
+#
+
+output:
+  internal/accesscontrolpolicyapi/accesscontrolpolicyapi.gen.go
+package: accesscontrolpolicyapi
+generate:
+  - server
+  - spec
+import-mapping:
+  TS29571_CommonData.yaml: oransc.org/nonrtric/sme/internal/common29571
diff --git a/gogeneratorspecs/accesscontrolpolicyapi/generator_settings_types.yaml b/gogeneratorspecs/accesscontrolpolicyapi/generator_settings_types.yaml
new file mode 100644 (file)
index 0000000..13feeef
--- /dev/null
@@ -0,0 +1,28 @@
+# -
+#   ========================LICENSE_START=================================
+#   O-RAN-SC
+#   %%
+#   Copyright (C) 2022: Nordix Foundation
+#   %%
+#   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.
+#   ========================LICENSE_END===================================
+#
+
+output:
+  internal/accesscontrolpolicyapi/accesscontrolpolicyapi-types.gen.go
+package: accesscontrolpolicyapi
+generate:
+  - types
+import-mapping:
+  TS29571_CommonData.yaml: oransc.org/nonrtric/sme/internal/common29571
+  TS29122_CommonData.yaml: oransc.org/nonrtric/sme/internal/common29122
\ No newline at end of file
diff --git a/gogeneratorspecs/aefsecurityapi/generator_settings_client.yaml b/gogeneratorspecs/aefsecurityapi/generator_settings_client.yaml
new file mode 100644 (file)
index 0000000..6f7c966
--- /dev/null
@@ -0,0 +1,27 @@
+# -
+#   ========================LICENSE_START=================================
+#   O-RAN-SC
+#   %%
+#   Copyright (C) 2022: Nordix Foundation
+#   %%
+#   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.
+#   ========================LICENSE_END===================================
+#
+
+output:
+  internal/aefsecurityapi/aefsecurityapi-client.gen.go
+package: aefsecurityapi
+generate:
+  - server
+import-mapping:
+  TS29571_CommonData.yaml: internal/common29571
diff --git a/gogeneratorspecs/aefsecurityapi/generator_settings_server.yaml b/gogeneratorspecs/aefsecurityapi/generator_settings_server.yaml
new file mode 100644 (file)
index 0000000..c889486
--- /dev/null
@@ -0,0 +1,28 @@
+# -
+#   ========================LICENSE_START=================================
+#   O-RAN-SC
+#   %%
+#   Copyright (C) 2022: Nordix Foundation
+#   %%
+#   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.
+#   ========================LICENSE_END===================================
+#
+
+output:
+  internal/aefsecurityapi/aefsecurityapi-server.gen.go
+package: aefsecurityapi
+generate:
+  - server
+  - spec
+import-mapping:
+  TS29571_CommonData.yaml: oransc.org/nonrtric/sme/internal/common29571
diff --git a/gogeneratorspecs/aefsecurityapi/generator_settings_types.yaml b/gogeneratorspecs/aefsecurityapi/generator_settings_types.yaml
new file mode 100644 (file)
index 0000000..f35eb9d
--- /dev/null
@@ -0,0 +1,29 @@
+# -
+#   ========================LICENSE_START=================================
+#   O-RAN-SC
+#   %%
+#   Copyright (C) 2022: Nordix Foundation
+#   %%
+#   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.
+#   ========================LICENSE_END===================================
+#
+
+output:
+  internal/aefsecurityapi/aefsecurityapi-types.gen.go
+package: aefsecurityapi
+generate:
+  - types
+import-mapping:
+  TS29571_CommonData.yaml: oransc.org/nonrtric/sme/internal/common29571
+  TS29122_CommonData.yaml: oransc.org/nonrtric/sme/internal/common29122
+  TS29222_CAPIF_Security_API.yaml: oransc.org/nonrtric/sme/internal/securityapi
\ No newline at end of file
diff --git a/gogeneratorspecs/auditingapi/generator_settings_client.yaml b/gogeneratorspecs/auditingapi/generator_settings_client.yaml
new file mode 100644 (file)
index 0000000..d7b9704
--- /dev/null
@@ -0,0 +1,30 @@
+# -
+#   ========================LICENSE_START=================================
+#   O-RAN-SC
+#   %%
+#   Copyright (C) 2022: Nordix Foundation
+#   %%
+#   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.
+#   ========================LICENSE_END===================================
+#
+
+output:
+  internal/auditingapi/auditingapi-client.gen.go
+package: auditingapi
+generate:
+  - client
+import-mapping:
+  TS29122_CommonData.yaml: internal/common29122
+  TS29571_CommonData.yaml: internal/common29571
+  TS29222_CAPIF_Publish_Service_API.yaml: internal/publishserviceapi
+  TS29222_CAPIF_Logging_API_Invocation_API.yaml: internal/loggingapi
\ No newline at end of file
diff --git a/gogeneratorspecs/auditingapi/generator_settings_server.yaml b/gogeneratorspecs/auditingapi/generator_settings_server.yaml
new file mode 100644 (file)
index 0000000..2984a2b
--- /dev/null
@@ -0,0 +1,30 @@
+# -
+#   ========================LICENSE_START=================================
+#   O-RAN-SC
+#   %%
+#   Copyright (C) 2022: Nordix Foundation
+#   %%
+#   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.
+#   ========================LICENSE_END===================================
+#
+
+output:
+  internal/auditingapi/auditingapi-server.gen.go
+package: auditingapi
+generate:
+  - server
+  - spec
+import-mapping:
+  TS29122_CommonData.yaml: oransc.org/nonrtric/sme/internal/common29122
+  TS29571_CommonData.yaml: oransc.org/nonrtric/sme/internal/common29571
+  TS29222_CAPIF_Publish_Service_API.yaml: oransc.org/nonrtric/sme/internal/publishserviceapi
\ No newline at end of file
diff --git a/gogeneratorspecs/auditingapi/generator_settings_types.yaml b/gogeneratorspecs/auditingapi/generator_settings_types.yaml
new file mode 100644 (file)
index 0000000..4c16309
--- /dev/null
@@ -0,0 +1,29 @@
+# -
+#   ========================LICENSE_START=================================
+#   O-RAN-SC
+#   %%
+#   Copyright (C) 2022: Nordix Foundation
+#   %%
+#   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.
+#   ========================LICENSE_END===================================
+#
+
+output:
+  internal/auditingapi/auditingapi-types.gen.go
+package: auditingapi
+generate:
+  - types
+import-mapping:
+  TS29122_CommonData.yaml: oransc.org/nonrtric/sme/internal/common29122
+  TS29571_CommonData.yaml: oransc.org/nonrtric/sme/internal/common29571
+  TS29222_CAPIF_Publish_Service_API.yaml: oransc.org/nonrtric/sme/internal/publishserviceapi
\ No newline at end of file
diff --git a/gogeneratorspecs/common/generator_settings.yaml b/gogeneratorspecs/common/generator_settings.yaml
new file mode 100644 (file)
index 0000000..df0b7c1
--- /dev/null
@@ -0,0 +1,29 @@
+# -
+#   ========================LICENSE_START=================================
+#   O-RAN-SC
+#   %%
+#   Copyright (C) 2022: Nordix Foundation
+#   %%
+#   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.
+#   ========================LICENSE_END===================================
+#
+
+output:
+  internal/common/common.gen.go
+package: common
+generate:
+  - types
+  - skip-prune
+  - spec
+import-mapping:
+  TS29571_CommonData.yaml: oransc.org/nonrtric/sme/internal/common29571
diff --git a/gogeneratorspecs/common29122/generator_settings.yaml b/gogeneratorspecs/common29122/generator_settings.yaml
new file mode 100644 (file)
index 0000000..469bc5b
--- /dev/null
@@ -0,0 +1,30 @@
+# -
+#   ========================LICENSE_START=================================
+#   O-RAN-SC
+#   %%
+#   Copyright (C) 2022: Nordix Foundation
+#   %%
+#   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.
+#   ========================LICENSE_END===================================
+#
+
+output:
+  internal/common29122/common29122.gen.go
+package: common29122
+generate:
+  - types
+  - skip-prune
+  - spec
+import-mapping:
+  TS29571_CommonData.yaml: oransc.org/nonrtric/sme/internal/common29571
+  CommonData.yaml: oransc.org/nonrtric/sme/internal/common
\ No newline at end of file
diff --git a/gogeneratorspecs/common29571/generator_settings.yaml b/gogeneratorspecs/common29571/generator_settings.yaml
new file mode 100644 (file)
index 0000000..757e1fc
--- /dev/null
@@ -0,0 +1,27 @@
+# -
+#   ========================LICENSE_START=================================
+#   O-RAN-SC
+#   %%
+#   Copyright (C) 2022: Nordix Foundation
+#   %%
+#   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.
+#   ========================LICENSE_END===================================
+#
+
+output:
+  internal/common29571/common29571.gen.go
+package: common29571
+generate:
+  - types
+  - skip-prune
+  - spec
diff --git a/gogeneratorspecs/discoverserviceapi/generator_settings_client.yaml b/gogeneratorspecs/discoverserviceapi/generator_settings_client.yaml
new file mode 100644 (file)
index 0000000..e7231b8
--- /dev/null
@@ -0,0 +1,29 @@
+# -
+#   ========================LICENSE_START=================================
+#   O-RAN-SC
+#   %%
+#   Copyright (C) 2022: Nordix Foundation
+#   %%
+#   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.
+#   ========================LICENSE_END===================================
+#
+
+output:
+  internal/discoverserviceapi/discoverserviceapi-client.gen.go
+package: discoverserviceapi
+generate:
+  - client
+import-mapping:
+  TS29122_CommonData.yaml: internal/common29122
+  TS29571_CommonData.yaml: internal/common29571
+  TS29222_CAPIF_Publish_Service_API.yaml: internal/publishserviceapi
\ No newline at end of file
diff --git a/gogeneratorspecs/discoverserviceapi/generator_settings_server.yaml b/gogeneratorspecs/discoverserviceapi/generator_settings_server.yaml
new file mode 100644 (file)
index 0000000..4f4b64f
--- /dev/null
@@ -0,0 +1,30 @@
+# -
+#   ========================LICENSE_START=================================
+#   O-RAN-SC
+#   %%
+#   Copyright (C) 2022: Nordix Foundation
+#   %%
+#   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.
+#   ========================LICENSE_END===================================
+#
+
+output:
+  internal/discoverserviceapi/discoverserviceapi-server.gen.go
+package: discoverserviceapi
+generate:
+  - server
+  - spec
+import-mapping:
+  TS29122_CommonData.yaml: oransc.org/nonrtric/sme/internal/common29122
+  TS29571_CommonData.yaml: oransc.org/nonrtric/sme/internal/common29571
+  TS29222_CAPIF_Publish_Service_API.yaml: oransc.org/nonrtric/sme/internal/publishserviceapi
\ No newline at end of file
diff --git a/gogeneratorspecs/discoverserviceapi/generator_settings_types.yaml b/gogeneratorspecs/discoverserviceapi/generator_settings_types.yaml
new file mode 100644 (file)
index 0000000..f2dce51
--- /dev/null
@@ -0,0 +1,29 @@
+# -
+#   ========================LICENSE_START=================================
+#   O-RAN-SC
+#   %%
+#   Copyright (C) 2022: Nordix Foundation
+#   %%
+#   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.
+#   ========================LICENSE_END===================================
+#
+
+output:
+  internal/discoverserviceapi/discoverserviceapi-types.gen.go
+package: discoverserviceapi
+generate:
+  - types
+import-mapping:
+  TS29122_CommonData.yaml: oransc.org/nonrtric/sme/internal/common29122
+  TS29571_CommonData.yaml: oransc.org/nonrtric/sme/internal/common29571
+  TS29222_CAPIF_Publish_Service_API.yaml: oransc.org/nonrtric/sme/internal/publishserviceapi
\ No newline at end of file
diff --git a/gogeneratorspecs/eventsapi/generator_settings_client.yaml b/gogeneratorspecs/eventsapi/generator_settings_client.yaml
new file mode 100644 (file)
index 0000000..8e88252
--- /dev/null
@@ -0,0 +1,25 @@
+# -
+#   ========================LICENSE_START=================================
+#   O-RAN-SC
+#   %%
+#   Copyright (C) 2022: Nordix Foundation
+#   %%
+#   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.
+#   ========================LICENSE_END===================================
+#
+
+output:
+  internal/eventsapi/eventsapi-client.gen.go
+package: eventsapi
+generate:
+  - client
\ No newline at end of file
diff --git a/gogeneratorspecs/eventsapi/generator_settings_server.yaml b/gogeneratorspecs/eventsapi/generator_settings_server.yaml
new file mode 100644 (file)
index 0000000..3f038be
--- /dev/null
@@ -0,0 +1,26 @@
+# -
+#   ========================LICENSE_START=================================
+#   O-RAN-SC
+#   %%
+#   Copyright (C) 2022: Nordix Foundation
+#   %%
+#   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.
+#   ========================LICENSE_END===================================
+#
+
+output:
+  internal/eventsapi/eventsapi-server.gen.go
+package: eventsapi
+generate:
+  - server
+  - spec
\ No newline at end of file
diff --git a/gogeneratorspecs/eventsapi/generator_settings_types.yaml b/gogeneratorspecs/eventsapi/generator_settings_types.yaml
new file mode 100644 (file)
index 0000000..de4e0fe
--- /dev/null
@@ -0,0 +1,33 @@
+# -
+#   ========================LICENSE_START=================================
+#   O-RAN-SC
+#   %%
+#   Copyright (C) 2022: Nordix Foundation
+#   %%
+#   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.
+#   ========================LICENSE_END===================================
+#
+
+output:
+  internal/eventsapi/eventsapi-types.gen.go
+package: eventsapi
+generate:
+  - types
+import-mapping:
+  TS29571_CommonData.yaml: oransc.org/nonrtric/sme/internal/common29571
+  TS29122_CommonData.yaml: oransc.org/nonrtric/sme/internal/common29122
+  CommonData.yaml: oransc.org/nonrtric/sme/internal/common
+  TS29222_CAPIF_Access_Control_Policy_API.yaml: oransc.org/nonrtric/sme/internal/accesscontrolpolicyapi
+  TS29222_CAPIF_Logging_API_Invocation_API.yaml: oransc.org/nonrtric/sme/internal/loggingapi
+  TS29222_CAPIF_Publish_Service_API.yaml: oransc.org/nonrtric/sme/internal/publishserviceapi
+  TS29222_CAPIF_Routing_Info_API.yaml: oransc.org/nonrtric/sme/internal/routinginfoapi
\ No newline at end of file
diff --git a/gogeneratorspecs/invokermanagementapi/generator_settings_client.yaml b/gogeneratorspecs/invokermanagementapi/generator_settings_client.yaml
new file mode 100644 (file)
index 0000000..fdce27c
--- /dev/null
@@ -0,0 +1,29 @@
+# -
+#   ========================LICENSE_START=================================
+#   O-RAN-SC
+#   %%
+#   Copyright (C) 2022: Nordix Foundation
+#   %%
+#   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.
+#   ========================LICENSE_END===================================
+#
+
+output:
+  internal/invokermanagementapi/invokermanagementapi-client.gen.go
+package: invokermanagementapi
+generate:
+  - client
+import-mapping:
+  TS29122_CommonData.yaml: internal/common29122
+  TS29571_CommonData.yaml: internal/common29571
+  TS29222_CAPIF_Publish_Service_API.yaml: internal/publishserviceapi
\ No newline at end of file
diff --git a/gogeneratorspecs/invokermanagementapi/generator_settings_server.yaml b/gogeneratorspecs/invokermanagementapi/generator_settings_server.yaml
new file mode 100644 (file)
index 0000000..505c98a
--- /dev/null
@@ -0,0 +1,30 @@
+# -
+#   ========================LICENSE_START=================================
+#   O-RAN-SC
+#   %%
+#   Copyright (C) 2022: Nordix Foundation
+#   %%
+#   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.
+#   ========================LICENSE_END===================================
+#
+
+output:
+  internal/invokermanagementapi/invokermanagementapi-server.gen.go
+package: invokermanagementapi
+generate:
+  - server
+  - spec
+import-mapping:
+  TS29122_CommonData.yaml: oransc.org/nonrtric/sme/internal/common29122
+  TS29571_CommonData.yaml: oransc.org/nonrtric/sme/internal/common29571
+  TS29222_CAPIF_Publish_Service_API.yaml: oransc.org/nonrtric/sme/internal/publishserviceapi
\ No newline at end of file
diff --git a/gogeneratorspecs/invokermanagementapi/generator_settings_types.yaml b/gogeneratorspecs/invokermanagementapi/generator_settings_types.yaml
new file mode 100644 (file)
index 0000000..e621841
--- /dev/null
@@ -0,0 +1,29 @@
+# -
+#   ========================LICENSE_START=================================
+#   O-RAN-SC
+#   %%
+#   Copyright (C) 2022: Nordix Foundation
+#   %%
+#   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.
+#   ========================LICENSE_END===================================
+#
+
+output:
+  internal/invokermanagementapi/invokermanagementapi-types.gen.go
+package: invokermanagementapi
+generate:
+  - types
+import-mapping:
+  TS29122_CommonData.yaml: oransc.org/nonrtric/sme/internal/common29122
+  TS29571_CommonData.yaml: oransc.org/nonrtric/sme/internal/common29571
+  TS29222_CAPIF_Publish_Service_API.yaml: oransc.org/nonrtric/sme/internal/publishserviceapi
\ No newline at end of file
diff --git a/gogeneratorspecs/loggingapi/generator_settings_client.yaml b/gogeneratorspecs/loggingapi/generator_settings_client.yaml
new file mode 100644 (file)
index 0000000..f9be788
--- /dev/null
@@ -0,0 +1,25 @@
+# -
+#   ========================LICENSE_START=================================
+#   O-RAN-SC
+#   %%
+#   Copyright (C) 2022: Nordix Foundation
+#   %%
+#   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.
+#   ========================LICENSE_END===================================
+#
+
+output:
+  internal/loggingapi/loggingapi-client.gen.go
+package: loggingapi
+generate:
+  - client
\ No newline at end of file
diff --git a/gogeneratorspecs/loggingapi/generator_settings_server.yaml b/gogeneratorspecs/loggingapi/generator_settings_server.yaml
new file mode 100644 (file)
index 0000000..99fe0a7
--- /dev/null
@@ -0,0 +1,26 @@
+# -
+#   ========================LICENSE_START=================================
+#   O-RAN-SC
+#   %%
+#   Copyright (C) 2022: Nordix Foundation
+#   %%
+#   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.
+#   ========================LICENSE_END===================================
+#
+
+output:
+  internal/loggingapi/loggingapi-server.gen.go
+package: loggingapi
+generate:
+  - server
+  - spec
\ No newline at end of file
diff --git a/gogeneratorspecs/loggingapi/generator_settings_types.yaml b/gogeneratorspecs/loggingapi/generator_settings_types.yaml
new file mode 100644 (file)
index 0000000..990711e
--- /dev/null
@@ -0,0 +1,29 @@
+# -
+#   ========================LICENSE_START=================================
+#   O-RAN-SC
+#   %%
+#   Copyright (C) 2022: Nordix Foundation
+#   %%
+#   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.
+#   ========================LICENSE_END===================================
+#
+
+output:
+  internal/loggingapi/loggingapi-types.gen.go
+package: loggingapi
+generate:
+  - types
+import-mapping:
+  TS29571_CommonData.yaml: oransc.org/nonrtric/sme/internal/common29571
+  TS29122_CommonData.yaml: oransc.org/nonrtric/sme/internal/common29122
+  TS29222_CAPIF_Publish_Service_API.yaml: oransc.org/nonrtric/sme/internal/publishserviceapi
\ No newline at end of file
diff --git a/gogeneratorspecs/providermanagementapi/generator_settings_client.yaml b/gogeneratorspecs/providermanagementapi/generator_settings_client.yaml
new file mode 100644 (file)
index 0000000..58c4b60
--- /dev/null
@@ -0,0 +1,28 @@
+# -
+#   ========================LICENSE_START=================================
+#   O-RAN-SC
+#   %%
+#   Copyright (C) 2022: Nordix Foundation
+#   %%
+#   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.
+#   ========================LICENSE_END===================================
+#
+
+output:
+  internal/providermanagementapi/providermanagementapi-client.gen.go
+package: providermanagementapi
+generate:
+  - client
+import-mapping:
+  TS29122_CommonData.yaml: internal/common29122
+  TS29571_CommonData.yaml: internal/common29571
\ No newline at end of file
diff --git a/gogeneratorspecs/providermanagementapi/generator_settings_server.yaml b/gogeneratorspecs/providermanagementapi/generator_settings_server.yaml
new file mode 100644 (file)
index 0000000..cad421d
--- /dev/null
@@ -0,0 +1,29 @@
+# -
+#   ========================LICENSE_START=================================
+#   O-RAN-SC
+#   %%
+#   Copyright (C) 2022: Nordix Foundation
+#   %%
+#   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.
+#   ========================LICENSE_END===================================
+#
+
+output:
+  internal/providermanagementapi/providermanagementapi-server.gen.go
+package: providermanagementapi
+generate:
+  - server
+  - spec
+import-mapping:
+  TS29122_CommonData.yaml: oransc.org/nonrtric/sme/internal/common29122
+  TS29571_CommonData.yaml: oransc.org/nonrtric/sme/internal/common29571
\ No newline at end of file
diff --git a/gogeneratorspecs/providermanagementapi/generator_settings_types.yaml b/gogeneratorspecs/providermanagementapi/generator_settings_types.yaml
new file mode 100644 (file)
index 0000000..5dd64f9
--- /dev/null
@@ -0,0 +1,28 @@
+# -
+#   ========================LICENSE_START=================================
+#   O-RAN-SC
+#   %%
+#   Copyright (C) 2022: Nordix Foundation
+#   %%
+#   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.
+#   ========================LICENSE_END===================================
+#
+
+output:
+  internal/providermanagementapi/providermanagementapi-types.gen.go
+package: providermanagementapi
+generate:
+  - types
+import-mapping:
+  TS29122_CommonData.yaml: oransc.org/nonrtric/sme/internal/common29122
+  TS29571_CommonData.yaml: oransc.org/nonrtric/sme/internal/common29571
\ No newline at end of file
diff --git a/gogeneratorspecs/publishserviceapi/generator_settings_client.yaml b/gogeneratorspecs/publishserviceapi/generator_settings_client.yaml
new file mode 100644 (file)
index 0000000..eee5e6d
--- /dev/null
@@ -0,0 +1,29 @@
+# -
+#   ========================LICENSE_START=================================
+#   O-RAN-SC
+#   %%
+#   Copyright (C) 2022: Nordix Foundation
+#   %%
+#   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.
+#   ========================LICENSE_END===================================
+#
+
+output:
+  internal/publishserviceapi/publishserviceapi-client.gen.go
+package: publishserviceapi
+generate:
+  - client
+import-mapping:
+  TS29122_CommonData.yaml: internal/common29122
+  TS29571_CommonData.yaml: internal/common29571
+  CommonData.yaml: internal/common
\ No newline at end of file
diff --git a/gogeneratorspecs/publishserviceapi/generator_settings_server.yaml b/gogeneratorspecs/publishserviceapi/generator_settings_server.yaml
new file mode 100644 (file)
index 0000000..01e2628
--- /dev/null
@@ -0,0 +1,30 @@
+# -
+#   ========================LICENSE_START=================================
+#   O-RAN-SC
+#   %%
+#   Copyright (C) 2022: Nordix Foundation
+#   %%
+#   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.
+#   ========================LICENSE_END===================================
+#
+
+output:
+  internal/publishserviceapi/publishserviceapi-server.gen.go
+package: publishserviceapi
+generate:
+  - server
+  - spec
+import-mapping:
+  TS29122_CommonData.yaml: oransc.org/nonrtric/sme/internal/common29122
+  TS29571_CommonData.yaml: oransc.org/nonrtric/sme/internal/common29571
+  CommonData.yaml: oransc.org/nonrtric/sme/internal/common
\ No newline at end of file
diff --git a/gogeneratorspecs/publishserviceapi/generator_settings_types.yaml b/gogeneratorspecs/publishserviceapi/generator_settings_types.yaml
new file mode 100644 (file)
index 0000000..4727683
--- /dev/null
@@ -0,0 +1,29 @@
+# -
+#   ========================LICENSE_START=================================
+#   O-RAN-SC
+#   %%
+#   Copyright (C) 2022: Nordix Foundation
+#   %%
+#   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.
+#   ========================LICENSE_END===================================
+#
+
+output:
+  internal/publishserviceapi/publishserviceapi-types.gen.go
+package: publishserviceapi
+generate:
+  - types
+import-mapping:
+  TS29122_CommonData.yaml: oransc.org/nonrtric/sme/internal/common29122
+  TS29571_CommonData.yaml: oransc.org/nonrtric/sme/internal/common29571
+  CommonData.yaml: oransc.org/nonrtric/sme/internal/common
\ No newline at end of file
diff --git a/gogeneratorspecs/routinginfoapi/generator_settings_client.yaml b/gogeneratorspecs/routinginfoapi/generator_settings_client.yaml
new file mode 100644 (file)
index 0000000..66c56bc
--- /dev/null
@@ -0,0 +1,29 @@
+# -
+#   ========================LICENSE_START=================================
+#   O-RAN-SC
+#   %%
+#   Copyright (C) 2022: Nordix Foundation
+#   %%
+#   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.
+#   ========================LICENSE_END===================================
+#
+
+output:
+  internal/routinginfoapi/routinginfoapi-client.gen.go
+package: routinginfoapi
+generate:
+  - client
+import-mapping:
+  TS29122_CommonData.yaml: internal/common29122
+  TS29571_CommonData.yaml: internal/common29571
+  TS29222_CAPIF_Publish_Service_API.yaml: internal/publishserviceapi
\ No newline at end of file
diff --git a/gogeneratorspecs/routinginfoapi/generator_settings_server.yaml b/gogeneratorspecs/routinginfoapi/generator_settings_server.yaml
new file mode 100644 (file)
index 0000000..4863d30
--- /dev/null
@@ -0,0 +1,30 @@
+# -
+#   ========================LICENSE_START=================================
+#   O-RAN-SC
+#   %%
+#   Copyright (C) 2022: Nordix Foundation
+#   %%
+#   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.
+#   ========================LICENSE_END===================================
+#
+
+output:
+  internal/routinginfoapi/routinginfoapi-server.gen.go
+package: routinginfoapi
+generate:
+  - server
+  - spec
+import-mapping:
+  TS29122_CommonData.yaml: oransc.org/nonrtric/sme/internal/common29122
+  TS29571_CommonData.yaml: oransc.org/nonrtric/sme/internal/common29571
+  TS29222_CAPIF_Publish_Service_API.yaml: oransc.org/nonrtric/sme/internal/publishserviceapi
\ No newline at end of file
diff --git a/gogeneratorspecs/routinginfoapi/generator_settings_types.yaml b/gogeneratorspecs/routinginfoapi/generator_settings_types.yaml
new file mode 100644 (file)
index 0000000..f9448e3
--- /dev/null
@@ -0,0 +1,30 @@
+# -
+#   ========================LICENSE_START=================================
+#   O-RAN-SC
+#   %%
+#   Copyright (C) 2022: Nordix Foundation
+#   %%
+#   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.
+#   ========================LICENSE_END===================================
+#
+
+output:
+  internal/routinginfoapi/routinginfoapi-types.gen.go
+package: routinginfoapi
+generate:
+  - types
+import-mapping:
+  TS29122_CommonData.yaml: oransc.org/nonrtric/sme/internal/common29122
+  TS29571_CommonData.yaml: oransc.org/nonrtric/sme/internal/common29571
+  CommonData.yaml: oransc.org/nonrtric/sme/internal/common
+  TS29222_CAPIF_Publish_Service_API.yaml: oransc.org/nonrtric/sme/internal/publishserviceapi
\ No newline at end of file
diff --git a/gogeneratorspecs/securityapi/generator_settings_client.yaml b/gogeneratorspecs/securityapi/generator_settings_client.yaml
new file mode 100644 (file)
index 0000000..409e527
--- /dev/null
@@ -0,0 +1,29 @@
+# -
+#   ========================LICENSE_START=================================
+#   O-RAN-SC
+#   %%
+#   Copyright (C) 2022: Nordix Foundation
+#   %%
+#   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.
+#   ========================LICENSE_END===================================
+#
+
+output:
+  internal/securityapi/securityapi-client.gen.go
+package: securityapi
+generate:
+  - client
+import-mapping:
+  TS29122_CommonData.yaml: internal/common29122
+  TS29571_CommonData.yaml: internal/common29571
+  TS29222_CAPIF_Publish_Service_API.yaml: internal/publishserviceapi
\ No newline at end of file
diff --git a/gogeneratorspecs/securityapi/generator_settings_server.yaml b/gogeneratorspecs/securityapi/generator_settings_server.yaml
new file mode 100644 (file)
index 0000000..5f685ad
--- /dev/null
@@ -0,0 +1,30 @@
+# -
+#   ========================LICENSE_START=================================
+#   O-RAN-SC
+#   %%
+#   Copyright (C) 2022: Nordix Foundation
+#   %%
+#   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.
+#   ========================LICENSE_END===================================
+#
+
+output:
+  internal/securityapi/securityapi-server.gen.go
+package: securityapi
+generate:
+  - server
+  - spec
+import-mapping:
+  TS29122_CommonData.yaml: oransc.org/nonrtric/sme/internal/common29122
+  TS29571_CommonData.yaml: oransc.org/nonrtric/sme/internal/common29571
+  TS29222_CAPIF_Publish_Service_API.yaml: oransc.org/nonrtric/sme/internal/publishserviceapi
\ No newline at end of file
diff --git a/gogeneratorspecs/securityapi/generator_settings_types.yaml b/gogeneratorspecs/securityapi/generator_settings_types.yaml
new file mode 100644 (file)
index 0000000..607fb7f
--- /dev/null
@@ -0,0 +1,29 @@
+# -
+#   ========================LICENSE_START=================================
+#   O-RAN-SC
+#   %%
+#   Copyright (C) 2022: Nordix Foundation
+#   %%
+#   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.
+#   ========================LICENSE_END===================================
+#
+
+output:
+  internal/securityapi/securityapi-types.gen.go
+package: securityapi
+generate:
+  - types
+import-mapping:
+  TS29122_CommonData.yaml: oransc.org/nonrtric/sme/internal/common29122
+  TS29571_CommonData.yaml: oransc.org/nonrtric/sme/internal/common29571
+  TS29222_CAPIF_Publish_Service_API.yaml: oransc.org/nonrtric/sme/internal/publishserviceapi
\ No newline at end of file
diff --git a/internal/discoverservice/discoverservice.go b/internal/discoverservice/discoverservice.go
new file mode 100644 (file)
index 0000000..1dccf85
--- /dev/null
@@ -0,0 +1,90 @@
+// -
+//   ========================LICENSE_START=================================
+//   O-RAN-SC
+//   %%
+//   Copyright (C) 2022: Nordix Foundation
+//   %%
+//   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.
+//   ========================LICENSE_END===================================
+//
+
+package discoverservice
+
+import (
+       "net/http"
+
+       discoverapi "oransc.org/nonrtric/sme/internal/discoverserviceapi"
+
+       "oransc.org/nonrtric/sme/internal/publishservice"
+
+       "github.com/labstack/echo/v4"
+
+       publishapi "oransc.org/nonrtric/sme/internal/publishserviceapi"
+)
+
+type DiscoverService struct {
+       apiRegister publishservice.APIRegister
+}
+
+func NewDiscoverService(apiRegister publishservice.APIRegister) *DiscoverService {
+       return &DiscoverService{
+               apiRegister: apiRegister,
+       }
+}
+
+func (ds *DiscoverService) GetAllServiceAPIs(ctx echo.Context, params discoverapi.GetAllServiceAPIsParams) error {
+       allApis := *ds.apiRegister.GetAPIs()
+       filteredApis := []publishapi.ServiceAPIDescription{}
+       gatewayDomain := "r1-expo-func-aef"
+       for _, api := range allApis {
+               if !matchesFilter(api, params) {
+                       continue
+               }
+               profiles := *api.AefProfiles
+               for i, profile := range profiles {
+                       profile.DomainName = &gatewayDomain // Hardcoded for now. Should be provided through some other mechanism.
+                       profiles[i] = profile
+               }
+               filteredApis = append(filteredApis, api)
+       }
+       discoveredApis := discoverapi.DiscoveredAPIs{
+               ServiceAPIDescriptions: &filteredApis,
+       }
+       err := ctx.JSON(http.StatusOK, discoveredApis)
+       if err != nil {
+               // Something really bad happened, tell Echo that our handler failed
+               return err
+       }
+
+       return nil
+}
+
+func matchesFilter(api publishapi.ServiceAPIDescription, filter discoverapi.GetAllServiceAPIsParams) bool {
+       if filter.ApiName != nil && *filter.ApiName != api.ApiName {
+               return false
+       }
+       profiles := *api.AefProfiles
+       match := false
+       for _, profile := range profiles {
+               if filter.ApiVersion != nil {
+                       for _, version := range profile.Versions {
+                               if *filter.ApiVersion == version.ApiVersion {
+                                       match = true
+                               }
+                       }
+               } else {
+                       match = true
+               }
+       }
+       return match
+}
diff --git a/internal/discoverservice/discoverservice_test.go b/internal/discoverservice/discoverservice_test.go
new file mode 100644 (file)
index 0000000..68067a9
--- /dev/null
@@ -0,0 +1,144 @@
+// -
+//   ========================LICENSE_START=================================
+//   O-RAN-SC
+//   %%
+//   Copyright (C) 2022: Nordix Foundation
+//   %%
+//   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.
+//   ========================LICENSE_END===================================
+//
+
+package discoverservice
+
+import (
+       "fmt"
+       "net/http"
+       "os"
+       "testing"
+
+       "oransc.org/nonrtric/sme/internal/discoverserviceapi"
+
+       "oransc.org/nonrtric/sme/internal/publishservice"
+
+       "github.com/labstack/echo/v4"
+
+       publishapi "oransc.org/nonrtric/sme/internal/publishserviceapi"
+
+       "oransc.org/nonrtric/sme/internal/publishservice/mocks"
+
+       "github.com/deepmap/oapi-codegen/pkg/middleware"
+       "github.com/deepmap/oapi-codegen/pkg/testutil"
+       echomiddleware "github.com/labstack/echo/v4/middleware"
+       "github.com/stretchr/testify/assert"
+)
+
+func TestGetAllServiceAPIs(t *testing.T) {
+       var err error
+
+       apiList := []publishapi.ServiceAPIDescription{
+               getAPI("apiName1", "v1"),
+               getAPI("apiName2", "v1"),
+       }
+       apiRegisterMock := mocks.APIRegister{}
+       apiRegisterMock.On("GetAPIs").Return(&apiList)
+       requestHandler := getEcho(&apiRegisterMock)
+
+       // Get all APIs, without any filter
+       result := testutil.NewRequest().Get("/allServiceAPIs?api-invoker-id=api_invoker_id").Go(t, requestHandler)
+
+       assert.Equal(t, http.StatusOK, result.Code())
+       var resultInvoker discoverserviceapi.DiscoveredAPIs
+       err = result.UnmarshalBodyToObject(&resultInvoker)
+       assert.NoError(t, err, "error unmarshaling response")
+       assert.Equal(t, 2, len(*resultInvoker.ServiceAPIDescriptions))
+       assert.Equal(t, "apiName1", (*resultInvoker.ServiceAPIDescriptions)[0].ApiName)
+       assert.Equal(t, "apiName2", (*resultInvoker.ServiceAPIDescriptions)[1].ApiName)
+       apiRegisterMock.AssertCalled(t, "GetAPIs")
+
+       // Get APIs with filter
+       result = testutil.NewRequest().Get("/allServiceAPIs?api-name=apiName1&api-version=v1&api-invoker-id=api_invoker_id").Go(t, requestHandler)
+
+       assert.Equal(t, http.StatusOK, result.Code())
+       err = result.UnmarshalBodyToObject(&resultInvoker)
+       assert.NoError(t, err, "error unmarshaling response")
+       assert.Equal(t, 1, len(*resultInvoker.ServiceAPIDescriptions))
+       assert.Equal(t, "apiName1", (*resultInvoker.ServiceAPIDescriptions)[0].ApiName)
+       apiRegisterMock.AssertCalled(t, "GetAPIs")
+}
+
+func getEcho(apiRegister publishservice.APIRegister) *echo.Echo {
+       swagger, err := discoverserviceapi.GetSwagger()
+       if err != nil {
+               fmt.Fprintf(os.Stderr, "Error loading swagger spec\n: %s", err)
+               os.Exit(1)
+       }
+
+       swagger.Servers = nil
+
+       ds := NewDiscoverService(apiRegister)
+
+       e := echo.New()
+       e.Use(echomiddleware.Logger())
+       e.Use(middleware.OapiRequestValidator(swagger))
+
+       discoverserviceapi.RegisterHandlers(e, ds)
+       return e
+}
+
+func getAPI(apiName, apiVersion string) publishapi.ServiceAPIDescription {
+       apiId := "apiId_" + apiName
+       aefId := "aefId"
+       description := "description"
+       domainName := "domain"
+       var protocol publishapi.Protocol = "HTTP_1_1"
+       return publishapi.ServiceAPIDescription{
+               ApiId:       &apiId,
+               ApiName:     apiName,
+               Description: &description,
+               AefProfiles: &[]publishapi.AefProfile{
+                       {
+                               AefId:      aefId,
+                               DomainName: &domainName,
+                               Protocol:   &protocol,
+                               Versions: []publishapi.Version{
+                                       {
+                                               ApiVersion: apiVersion,
+                                               Resources: &[]publishapi.Resource{
+                                                       {
+                                                               ResourceName: "app",
+                                                               CommType:     "REQUEST_RESPONSE",
+                                                               Uri:          "uri",
+                                                               Operations: &[]publishapi.Operation{
+                                                                       "POST",
+                                                               },
+                                                       },
+                                               },
+                                       },
+                                       {
+                                               ApiVersion: "v2",
+                                               Resources: &[]publishapi.Resource{
+                                                       {
+                                                               ResourceName: "app",
+                                                               CommType:     "REQUEST_RESPONSE",
+                                                               Uri:          "uri",
+                                                               Operations: &[]publishapi.Operation{
+                                                                       "POST",
+                                                               },
+                                                       },
+                                               },
+                                       },
+                               },
+                       },
+               },
+       }
+}
diff --git a/internal/gentools/commoncollector/commoncollector.go b/internal/gentools/commoncollector/commoncollector.go
new file mode 100644 (file)
index 0000000..ab85e0a
--- /dev/null
@@ -0,0 +1,119 @@
+// -
+//   ========================LICENSE_START=================================
+//   O-RAN-SC
+//   %%
+//   Copyright (C) 2022: Nordix Foundation
+//   %%
+//   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.
+//   ========================LICENSE_END===================================
+//
+
+package main
+
+import (
+       "bufio"
+       "flag"
+       "io/ioutil"
+       "log"
+       "os"
+       "strings"
+
+       "gopkg.in/yaml.v2"
+)
+
+var apiDir *string
+var common = map[interface{}]interface{}{
+       "openapi": "3.0.0",
+       "info": map[interface{}]interface{}{
+               "title":   "Common",
+               "version": "1.0.0",
+       },
+       "components": map[interface{}]interface{}{
+               "schemas": map[interface{}]interface{}{},
+       },
+}
+
+func main() {
+       apiDir = flag.String("apidir", "", "Directory containing API definitions to fix")
+       flag.Parse()
+
+       file, err := os.Open("definitions.txt")
+       if err != nil {
+               log.Fatalf("Error opening file: %v", err)
+       }
+       defer func(file *os.File) {
+               _ = file.Close()
+       }(file)
+
+       scanner := bufio.NewScanner(file)
+       components := common["components"]
+       cMap := components.(map[interface{}]interface{})
+       schemas := cMap["schemas"].(map[interface{}]interface{})
+       for scanner.Scan() {
+               name, data := getDependency(scanner.Text())
+               if name == "EthFlowDescription" {
+                       changeToLocalReference("fDir", "FlowDirection", data)
+               }
+               if name == "ReportingInformation" {
+                       changeToLocalReference("notifMethod", "NotificationMethod", data)
+               }
+               if name == "RelativeCartesianLocation" {
+                       properties := data["properties"].(map[interface{}]interface{})
+                       delete(properties, true)
+                       data["required"] = remove(data["required"].([]interface{}), 1)
+               }
+               schemas[name] = data
+       }
+
+       if err := scanner.Err(); err != nil {
+               log.Fatal(err)
+       }
+
+       modCommon, err := yaml.Marshal(common)
+       if err != nil {
+               log.Fatalf("Marshal: #%v ", err)
+       }
+       err = ioutil.WriteFile(*apiDir+"/"+"CommonData.yaml", modCommon, 0644)
+       if err != nil {
+               log.Fatalf("Error writing yamlFile. #%v ", err)
+       }
+}
+
+func changeToLocalReference(attrname, refName string, data map[interface{}]interface{}) {
+       properties := data["properties"].(map[interface{}]interface{})
+       ref := properties[attrname].(map[interface{}]interface{})
+       ref["$ref"] = "#/components/schemas/" + refName
+}
+
+func getDependency(s string) (string, map[interface{}]interface{}) {
+       info := strings.Split(s, "#")
+       yamlFile, err := ioutil.ReadFile(*apiDir + "/" + info[0])
+       if err != nil {
+               log.Fatalf("Error reading yamlFile. #%v ", err)
+       }
+       m := make(map[string]interface{})
+       err = yaml.Unmarshal(yamlFile, m)
+       if err != nil {
+               log.Fatalf("Unmarshal: %v", err)
+       }
+       components := m["components"]
+       cMap := components.(map[interface{}]interface{})
+       schemas := cMap["schemas"].(map[interface{}]interface{})
+       component := strings.Split(info[1], "/")
+       dep := schemas[component[3]].(map[interface{}]interface{})
+       return component[3], dep
+}
+
+func remove(slice []interface{}, s int) []interface{} {
+       return append(slice[:s], slice[s+1:]...)
+}
diff --git a/internal/gentools/commoncollector/definitions.txt b/internal/gentools/commoncollector/definitions.txt
new file mode 100644 (file)
index 0000000..a2f3f25
--- /dev/null
@@ -0,0 +1,38 @@
+TS29508_Nsmf_EventExposure.yaml#/components/schemas/NotificationMethod
+TS29510_Nnrf_NFManagement.yaml#/components/schemas/Ipv4AddressRange
+TS29512_Npcf_SMPolicyControl.yaml#/components/schemas/FlowDirection
+TS29514_Npcf_PolicyAuthorization.yaml#/components/schemas/ContentVersion
+TS29514_Npcf_PolicyAuthorization.yaml#/components/schemas/EthFlowDescription
+TS29514_Npcf_PolicyAuthorization.yaml#/components/schemas/FlowDescription
+TS29514_Npcf_PolicyAuthorization.yaml#/components/schemas/TscaiInputContainer
+TS29517_Naf_EventExposure.yaml#/components/schemas/AddrFqdn
+TS29518_Namf_EventExposure.yaml#/components/schemas/CommunicationFailure
+TS29522_TrafficInfluence.yaml#/components/schemas/AfResultInfo
+TS29522_TrafficInfluence.yaml#/components/schemas/AfResultStatus
+TS29523_Npcf_EventExposure.yaml#/components/schemas/ReportingInformation
+TS29554_Npcf_BDTPolicyControl.yaml#/components/schemas/NetworkAreaInfo
+TS29572_Nlmf_Location.yaml#/components/schemas/Altitude
+TS29572_Nlmf_Location.yaml#/components/schemas/Angle
+TS29572_Nlmf_Location.yaml#/components/schemas/CivicAddress
+TS29572_Nlmf_Location.yaml#/components/schemas/Confidence
+TS29572_Nlmf_Location.yaml#/components/schemas/EllipsoidArc
+TS29572_Nlmf_Location.yaml#/components/schemas/GADShape
+TS29572_Nlmf_Location.yaml#/components/schemas/GeographicArea
+TS29572_Nlmf_Location.yaml#/components/schemas/GeographicalCoordinates
+TS29572_Nlmf_Location.yaml#/components/schemas/InnerRadius
+TS29572_Nlmf_Location.yaml#/components/schemas/Local2dPointUncertaintyEllipse
+TS29572_Nlmf_Location.yaml#/components/schemas/Local3dPointUncertaintyEllipsoid
+TS29572_Nlmf_Location.yaml#/components/schemas/LocalOrigin
+TS29572_Nlmf_Location.yaml#/components/schemas/Orientation
+TS29572_Nlmf_Location.yaml#/components/schemas/Point
+TS29572_Nlmf_Location.yaml#/components/schemas/PointAltitude
+TS29572_Nlmf_Location.yaml#/components/schemas/PointAltitudeUncertainty
+TS29572_Nlmf_Location.yaml#/components/schemas/PointList
+TS29572_Nlmf_Location.yaml#/components/schemas/PointUncertaintyCircle
+TS29572_Nlmf_Location.yaml#/components/schemas/PointUncertaintyEllipse
+TS29572_Nlmf_Location.yaml#/components/schemas/Polygon
+TS29572_Nlmf_Location.yaml#/components/schemas/RelativeCartesianLocation
+TS29572_Nlmf_Location.yaml#/components/schemas/Uncertainty
+TS29572_Nlmf_Location.yaml#/components/schemas/UncertaintyEllipsoid
+TS29572_Nlmf_Location.yaml#/components/schemas/SupportedGADShapes
+TS29572_Nlmf_Location.yaml#/components/schemas/UncertaintyEllipse
\ No newline at end of file
diff --git a/internal/gentools/enumfixer/enumfixer.go b/internal/gentools/enumfixer/enumfixer.go
new file mode 100644 (file)
index 0000000..b44c55c
--- /dev/null
@@ -0,0 +1,115 @@
+// -
+//   ========================LICENSE_START=================================
+//   O-RAN-SC
+//   %%
+//   Copyright (C) 2022: Nordix Foundation
+//   %%
+//   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.
+//   ========================LICENSE_END===================================
+//
+
+package main
+
+import (
+       "flag"
+       "fmt"
+       "io/ioutil"
+       "log"
+       "os"
+       "path/filepath"
+       "reflect"
+       "strconv"
+       "strings"
+
+       "gopkg.in/yaml.v2"
+)
+
+type Enum struct {
+       Enum        []string `yaml:"enum"`
+       Type        string   `yaml:"type"`
+       Description string   `yaml:"description"`
+}
+
+func main() {
+       var apiDir = flag.String("apidir", "", "Directory containing API definitions to fix")
+       flag.Parse()
+       err := filepath.Walk(*apiDir, fixEnums)
+       if err != nil {
+               fmt.Println(err)
+       }
+}
+
+func fixEnums(path string, info os.FileInfo, _ error) error {
+       if !info.IsDir() && strings.HasSuffix(info.Name(), ".yaml") {
+               yamlFile, err := ioutil.ReadFile(path)
+               if err != nil {
+                       log.Printf("yamlFile. Get err   #%v ", err)
+               }
+               m := make(map[string]interface{})
+               err = yaml.Unmarshal(yamlFile, m)
+               if err != nil {
+                       log.Fatalf("Unmarshal: %v", err)
+               }
+               components := m["components"]
+               if components != nil {
+                       cMap := components.(map[interface{}]interface{})
+                       schemas := cMap["schemas"].(map[interface{}]interface{})
+                       for typeName, typeDef := range schemas {
+                               tDMap := typeDef.(map[interface{}]interface{})
+                               anyOf, ok := tDMap["anyOf"]
+                               if ok {
+                                       aOSlice := anyOf.([]interface{})
+                                       correctEnum := Enum{}
+                                       mapInterface := aOSlice[0].(map[interface{}]interface{})
+                                       enumInterface := mapInterface["enum"]
+                                       if enumInterface != nil {
+                                               is := enumInterface.([]interface{})
+                                               var enumVals []string
+                                               for i := 0; i < len(is); i++ {
+                                                       if reflect.TypeOf(is[i]).Kind() == reflect.String {
+                                                               enumVals = append(enumVals, is[i].(string))
+
+                                                       } else if reflect.TypeOf(is[1]).Kind() == reflect.Int {
+                                                               enumVals = append(enumVals, strconv.Itoa(is[i].(int)))
+                                                       }
+                                               }
+                                               correctEnum.Enum = enumVals
+                                               correctEnum.Type = "string"
+                                               description := tDMap["description"]
+                                               if description != nil {
+                                                       correctEnum.Description = description.(string)
+                                               } else {
+                                                       if aOSlice[1] != nil {
+                                                               mapInterface = aOSlice[1].(map[interface{}]interface{})
+                                                               description := mapInterface["description"]
+                                                               if description != nil {
+                                                                       correctEnum.Description = description.(string)
+                                                               }
+                                                       }
+                                               }
+                                               schemas[typeName] = correctEnum
+                                       }
+                               }
+                       }
+                       modM, err := yaml.Marshal(m)
+                       if err != nil {
+                               log.Printf("yamlFile. Get err   #%v ", err)
+                       }
+                       err = ioutil.WriteFile(path, modM, 0644)
+                       if err != nil {
+                               log.Printf("yamlFile. Get err   #%v ", err)
+                       }
+               }
+       }
+       return nil
+}
diff --git a/internal/gentools/specificationfixer/specificationfixer.go b/internal/gentools/specificationfixer/specificationfixer.go
new file mode 100644 (file)
index 0000000..2efbf4b
--- /dev/null
@@ -0,0 +1,71 @@
+// -
+//   ========================LICENSE_START=================================
+//   O-RAN-SC
+//   %%
+//   Copyright (C) 2022: Nordix Foundation
+//   %%
+//   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.
+//   ========================LICENSE_END===================================
+//
+
+package main
+
+import (
+       "flag"
+       "io/ioutil"
+       "log"
+
+       "gopkg.in/yaml.v2"
+)
+
+var apiDir *string
+
+func main() {
+       apiDir = flag.String("apidir", "", "Directory containing API definitions to fix")
+       flag.Parse()
+
+       m := getData("TS29571_CommonData.yaml")
+       components := m["components"]
+       cMap := components.(map[interface{}]interface{})
+       schemas := cMap["schemas"].(map[interface{}]interface{})
+       snssaiExtensionData := schemas["SnssaiExtension"].(map[interface{}]interface{})
+       props := snssaiExtensionData["properties"].(map[interface{}]interface{})
+       wildcardSdData := props["wildcardSd"].(map[interface{}]interface{})
+       delete(wildcardSdData, "enum")
+
+       writeFile("TS29571_CommonData.yaml", m)
+}
+
+func getData(filename string) map[string]interface{} {
+       yamlFile, err := ioutil.ReadFile(*apiDir + "/" + filename)
+       if err != nil {
+               log.Fatalf("Error reading yamlFile. #%v ", err)
+       }
+       m := make(map[string]interface{})
+       err = yaml.Unmarshal(yamlFile, m)
+       if err != nil {
+               log.Fatalf("Unmarshal: %v", err)
+       }
+       return m
+}
+
+func writeFile(filename string, data map[string]interface{}) {
+       modCommon, err := yaml.Marshal(data)
+       if err != nil {
+               log.Fatalf("Marshal: #%v ", err)
+       }
+       err = ioutil.WriteFile(*apiDir+"/"+filename, modCommon, 0644)
+       if err != nil {
+               log.Fatalf("Error writing yamlFile. #%v ", err)
+       }
+}
diff --git a/internal/helmmanagement/helm.go b/internal/helmmanagement/helm.go
new file mode 100644 (file)
index 0000000..cfed6eb
--- /dev/null
@@ -0,0 +1,187 @@
+// -
+//   ========================LICENSE_START=================================
+//   O-RAN-SC
+//   %%
+//   Copyright (C) 2022: Nordix Foundation
+//   %%
+//   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.
+//   ========================LICENSE_END===================================
+//
+
+package helmmanagement
+
+import (
+       "fmt"
+       "io/ioutil"
+       "os"
+       "path/filepath"
+
+       "github.com/pkg/errors"
+       log "github.com/sirupsen/logrus"
+       "gopkg.in/yaml.v2"
+       "helm.sh/helm/v3/pkg/action"
+       "helm.sh/helm/v3/pkg/chart/loader"
+       "helm.sh/helm/v3/pkg/cli"
+       "helm.sh/helm/v3/pkg/getter"
+       "helm.sh/helm/v3/pkg/kube"
+       "helm.sh/helm/v3/pkg/repo"
+       "k8s.io/cli-runtime/pkg/genericclioptions"
+       "k8s.io/client-go/rest"
+)
+
+//go:generate mockery --name HelmManager
+type HelmManager interface {
+       AddToRepo(repoName, url string) error
+       InstallHelmChart(namespace, repoName, chartName, releaseName string) error
+       UninstallHelmChart(namespace, chartName string)
+}
+
+type helmManagerImpl struct {
+       settings *cli.EnvSettings
+}
+
+func NewHelmManager() *helmManagerImpl {
+       return &helmManagerImpl{
+               settings: cli.New(),
+       }
+}
+
+func (hm *helmManagerImpl) AddToRepo(repoName, url string) error {
+       repoFile := hm.settings.RepositoryConfig
+
+       //Ensure the file directory exists as it is required for file locking
+       err := os.MkdirAll(filepath.Dir(repoFile), os.ModePerm)
+       if err != nil && !os.IsExist(err) {
+               return err
+       }
+
+       b, err := ioutil.ReadFile(repoFile)
+       if err != nil && !os.IsNotExist(err) {
+               return err
+       }
+
+       var f repo.File
+       if err := yaml.Unmarshal(b, &f); err != nil {
+               return err
+       }
+
+       if f.Has(repoName) {
+               fmt.Printf("repository name (%s) already exists\n", repoName)
+               return nil
+       }
+
+       c := repo.Entry{
+               Name: repoName,
+               URL:  url,
+       }
+
+       r, err := repo.NewChartRepository(&c, getter.All(hm.settings))
+       if err != nil {
+               return err
+       }
+
+       if _, err := r.DownloadIndexFile(); err != nil {
+               err := errors.Wrapf(err, "looks like %q is not a valid chart repository or cannot be reached", url)
+               return err
+       }
+
+       f.Update(&c)
+
+       if err := f.WriteFile(repoFile, 0644); err != nil {
+               return err
+       }
+       fmt.Printf("%q has been added to your repositories\n", repoName)
+       return nil
+}
+
+func (hm *helmManagerImpl) InstallHelmChart(namespace, repoName, chartName, releaseName string) error {
+       actionConfig, err := getActionConfig(namespace)
+       if err != nil {
+               return err
+       }
+
+       install := action.NewInstall(actionConfig)
+
+       cp, err := install.ChartPathOptions.LocateChart(fmt.Sprintf("%s/%s", repoName, chartName), hm.settings)
+       if err != nil {
+               log.Error("Unable to locate chart!")
+               return err
+       }
+
+       chartRequested, err := loader.Load(cp)
+       if err != nil {
+               log.Error("Unable to load chart path!")
+               return err
+       }
+
+       install.Namespace = namespace
+       install.ReleaseName = releaseName
+       _, err = install.Run(chartRequested, nil)
+       if err != nil {
+               log.Error("Unable to run chart!")
+               return err
+       }
+       log.Debug("Successfully onboarded ", namespace, repoName, chartName, releaseName)
+       return nil
+}
+
+func (hm *helmManagerImpl) UninstallHelmChart(namespace, chartName string) {
+       actionConfig, err := getActionConfig(namespace)
+       if err != nil {
+               fmt.Println(err)
+       }
+
+       iCli := action.NewUninstall(actionConfig)
+
+       resp, err := iCli.Run(chartName)
+       if err != nil {
+               fmt.Println(err)
+       }
+       log.Debug("Successfully uninstalled chart: ", resp.Release.Name)
+}
+
+func getActionConfig(namespace string) (*action.Configuration, error) {
+       actionConfig := new(action.Configuration)
+       // Create the rest config instance with ServiceAccount values loaded in them
+       config, err := rest.InClusterConfig()
+       if err != nil {
+               // fallback to kubeconfig
+               home, exists := os.LookupEnv("HOME")
+               if !exists {
+                       home = "/root"
+               }
+               kubeconfigPath := filepath.Join(home, ".kube", "config")
+               if envvar := os.Getenv("KUBECONFIG"); len(envvar) > 0 {
+                       kubeconfigPath = envvar
+               }
+               if err := actionConfig.Init(kube.GetConfig(kubeconfigPath, "", namespace), namespace, os.Getenv("HELM_DRIVER"),
+                       func(format string, v ...interface{}) {
+                               fmt.Sprintf(format, v)
+                       }); err != nil {
+                       fmt.Println(err)
+               }
+       } else {
+               // Create the ConfigFlags struct instance with initialized values from ServiceAccount
+               kubeConfig := genericclioptions.NewConfigFlags(false)
+               kubeConfig.APIServer = &config.Host
+               kubeConfig.BearerToken = &config.BearerToken
+               kubeConfig.CAFile = &config.CAFile
+               kubeConfig.Namespace = &namespace
+               if err := actionConfig.Init(kubeConfig, namespace, os.Getenv("HELM_DRIVER"), func(format string, v ...interface{}) {
+                       fmt.Sprintf(format, v)
+               }); err != nil {
+                       fmt.Println(err)
+               }
+       }
+       return actionConfig, err
+}
diff --git a/internal/helmmanagement/mocks/HelmManager.go b/internal/helmmanagement/mocks/HelmManager.go
new file mode 100644 (file)
index 0000000..ead02ae
--- /dev/null
@@ -0,0 +1,58 @@
+// Code generated by mockery v2.14.0. DO NOT EDIT.
+
+package mocks
+
+import mock "github.com/stretchr/testify/mock"
+
+// HelmManager is an autogenerated mock type for the HelmManager type
+type HelmManager struct {
+       mock.Mock
+}
+
+// AddToRepo provides a mock function with given fields: repoName, url
+func (_m *HelmManager) AddToRepo(repoName string, url string) error {
+       ret := _m.Called(repoName, url)
+
+       var r0 error
+       if rf, ok := ret.Get(0).(func(string, string) error); ok {
+               r0 = rf(repoName, url)
+       } else {
+               r0 = ret.Error(0)
+       }
+
+       return r0
+}
+
+// InstallHelmChart provides a mock function with given fields: namespace, repoName, chartName, releaseName
+func (_m *HelmManager) InstallHelmChart(namespace string, repoName string, chartName string, releaseName string) error {
+       ret := _m.Called(namespace, repoName, chartName, releaseName)
+
+       var r0 error
+       if rf, ok := ret.Get(0).(func(string, string, string, string) error); ok {
+               r0 = rf(namespace, repoName, chartName, releaseName)
+       } else {
+               r0 = ret.Error(0)
+       }
+
+       return r0
+}
+
+// UninstallHelmChart provides a mock function with given fields: namespace, chartName
+func (_m *HelmManager) UninstallHelmChart(namespace string, chartName string) {
+       _m.Called(namespace, chartName)
+}
+
+type mockConstructorTestingTNewHelmManager interface {
+       mock.TestingT
+       Cleanup(func())
+}
+
+// NewHelmManager creates a new instance of HelmManager. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewHelmManager(t mockConstructorTestingTNewHelmManager) *HelmManager {
+       mock := &HelmManager{}
+       mock.Mock.Test(t)
+
+       t.Cleanup(func() { mock.AssertExpectations(t) })
+
+       return mock
+}
diff --git a/internal/invokermanagement/invokermanagement.go b/internal/invokermanagement/invokermanagement.go
new file mode 100644 (file)
index 0000000..571d2a0
--- /dev/null
@@ -0,0 +1,207 @@
+// -
+//   ========================LICENSE_START=================================
+//   O-RAN-SC
+//   %%
+//   Copyright (C) 2022: Nordix Foundation
+//   %%
+//   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.
+//   ========================LICENSE_END===================================
+//
+
+package invokermanagement
+
+import (
+       "net/http"
+       "path"
+       "strconv"
+       "strings"
+       "sync"
+
+       publishapi "oransc.org/nonrtric/sme/internal/publishserviceapi"
+
+       "oransc.org/nonrtric/sme/internal/common29122"
+       invokerapi "oransc.org/nonrtric/sme/internal/invokermanagementapi"
+
+       "oransc.org/nonrtric/sme/internal/publishservice"
+
+       "github.com/labstack/echo/v4"
+)
+
+//go:generate mockery --name InvokerRegister
+type InvokerRegister interface {
+       IsInvokerRegistered(invokerId string) bool
+       VerifyInvokerSecret(invokerId, secret string) bool
+}
+
+type InvokerManager struct {
+       onboardedInvokers map[string]invokerapi.APIInvokerEnrolmentDetails
+       apiRegister       publishservice.APIRegister
+       nextId            int64
+       lock              sync.Mutex
+}
+
+func NewInvokerManager(apiRegister publishservice.APIRegister) *InvokerManager {
+       return &InvokerManager{
+               onboardedInvokers: make(map[string]invokerapi.APIInvokerEnrolmentDetails),
+               apiRegister:       apiRegister,
+               nextId:            1000,
+       }
+}
+
+func (im *InvokerManager) IsInvokerRegistered(invokerId string) bool {
+       im.lock.Lock()
+       defer im.lock.Unlock()
+
+       _, registered := im.onboardedInvokers[invokerId]
+       return registered
+}
+
+func (im *InvokerManager) VerifyInvokerSecret(invokerId, secret string) bool {
+       im.lock.Lock()
+       defer im.lock.Unlock()
+
+       verified := false
+       if invoker, registered := im.onboardedInvokers[invokerId]; registered {
+               verified = *invoker.OnboardingInformation.OnboardingSecret == secret
+       }
+       return verified
+}
+
+func (im *InvokerManager) PostOnboardedInvokers(ctx echo.Context) error {
+       var newInvoker invokerapi.APIInvokerEnrolmentDetails
+       err := ctx.Bind(&newInvoker)
+       if err != nil {
+               return sendCoreError(ctx, http.StatusBadRequest, "Invalid format for invoker")
+       }
+
+       shouldReturn, coreError := im.validateInvoker(newInvoker, ctx)
+       if shouldReturn {
+               return coreError
+       }
+
+       im.lock.Lock()
+       defer im.lock.Unlock()
+
+       newInvoker.ApiInvokerId = im.getId(newInvoker.ApiInvokerInformation)
+       onboardingSecret := "onboarding_secret_"
+       if newInvoker.ApiInvokerInformation != nil {
+               onboardingSecret = onboardingSecret + strings.ReplaceAll(*newInvoker.ApiInvokerInformation, " ", "_")
+       } else {
+               onboardingSecret = onboardingSecret + *newInvoker.ApiInvokerId
+       }
+       newInvoker.OnboardingInformation.OnboardingSecret = &onboardingSecret
+
+       im.onboardedInvokers[*newInvoker.ApiInvokerId] = newInvoker
+
+       uri := ctx.Request().Host + ctx.Request().URL.String()
+       ctx.Response().Header().Set(echo.HeaderLocation, ctx.Scheme()+`://`+path.Join(uri, *newInvoker.ApiInvokerId))
+       err = ctx.JSON(http.StatusCreated, newInvoker)
+       if err != nil {
+               // Something really bad happened, tell Echo that our handler failed
+               return err
+       }
+
+       return nil
+}
+
+func (im *InvokerManager) DeleteOnboardedInvokersOnboardingId(ctx echo.Context, onboardingId string) error {
+       im.lock.Lock()
+       defer im.lock.Unlock()
+
+       delete(im.onboardedInvokers, onboardingId)
+
+       return ctx.NoContent(http.StatusNoContent)
+}
+
+func (im *InvokerManager) PutOnboardedInvokersOnboardingId(ctx echo.Context, onboardingId string) error {
+       var invoker invokerapi.APIInvokerEnrolmentDetails
+       err := ctx.Bind(&invoker)
+       if err != nil {
+               return sendCoreError(ctx, http.StatusBadRequest, "Invalid format for invoker")
+       }
+
+       if onboardingId != *invoker.ApiInvokerId {
+               return sendCoreError(ctx, http.StatusBadRequest, "Invoker ApiInvokerId not matching")
+       }
+
+       shouldReturn, coreError := im.validateInvoker(invoker, ctx)
+       if shouldReturn {
+               return coreError
+       }
+
+       im.lock.Lock()
+       defer im.lock.Unlock()
+
+       if _, ok := im.onboardedInvokers[onboardingId]; ok {
+               im.onboardedInvokers[*invoker.ApiInvokerId] = invoker
+       } else {
+               return sendCoreError(ctx, http.StatusNotFound, "The invoker to update has not been onboarded")
+       }
+
+       err = ctx.JSON(http.StatusOK, invoker)
+       if err != nil {
+               // Something really bad happened, tell Echo that our handler failed
+               return err
+       }
+
+       return nil
+}
+
+func (im *InvokerManager) ModifyIndApiInvokeEnrolment(ctx echo.Context, onboardingId string) error {
+       return ctx.NoContent(http.StatusNotImplemented)
+}
+
+func (im *InvokerManager) validateInvoker(invoker invokerapi.APIInvokerEnrolmentDetails, ctx echo.Context) (bool, error) {
+       if invoker.NotificationDestination == "" {
+               return true, sendCoreError(ctx, http.StatusBadRequest, "Invoker missing required NotificationDestination")
+       }
+
+       if invoker.OnboardingInformation.ApiInvokerPublicKey == "" {
+               return true, sendCoreError(ctx, http.StatusBadRequest, "Invoker missing required OnboardingInformation.ApiInvokerPublicKey")
+       }
+
+       if !im.areAPIsRegistered(invoker.ApiList) {
+               return true, sendCoreError(ctx, http.StatusBadRequest, "Some APIs needed by invoker are not registered")
+       }
+
+       return false, nil
+}
+
+func (im *InvokerManager) areAPIsRegistered(apis *invokerapi.APIList) bool {
+       if apis == nil {
+               return true
+       }
+       return im.apiRegister.AreAPIsRegistered((*[]publishapi.ServiceAPIDescription)(apis))
+}
+
+func (im *InvokerManager) getId(invokerInfo *string) *string {
+       idAsString := "api_invoker_id_"
+       if invokerInfo != nil {
+               idAsString = idAsString + strings.ReplaceAll(*invokerInfo, " ", "_")
+       } else {
+               idAsString = idAsString + strconv.FormatInt(im.nextId, 10)
+               im.nextId = im.nextId + 1
+       }
+       return &idAsString
+}
+
+// This function wraps sending of an error in the Error format, and
+// handling the failure to marshal that.
+func sendCoreError(ctx echo.Context, code int, message string) error {
+       pd := common29122.ProblemDetails{
+               Cause:  &message,
+               Status: &code,
+       }
+       err := ctx.JSON(code, pd)
+       return err
+}
diff --git a/internal/invokermanagement/invokermanagement_test.go b/internal/invokermanagement/invokermanagement_test.go
new file mode 100644 (file)
index 0000000..0b7b924
--- /dev/null
@@ -0,0 +1,270 @@
+// -
+//   ========================LICENSE_START=================================
+//   O-RAN-SC
+//   %%
+//   Copyright (C) 2022: Nordix Foundation
+//   %%
+//   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.
+//   ========================LICENSE_END===================================
+//
+package invokermanagement
+
+import (
+       "fmt"
+       "net/http"
+       "os"
+       "testing"
+
+       "oransc.org/nonrtric/sme/internal/invokermanagementapi"
+
+       "github.com/labstack/echo/v4"
+
+       "oransc.org/nonrtric/sme/internal/common29122"
+       "oransc.org/nonrtric/sme/internal/publishserviceapi"
+
+       "oransc.org/nonrtric/sme/internal/publishservice"
+       publishmocks "oransc.org/nonrtric/sme/internal/publishservice/mocks"
+
+       "github.com/deepmap/oapi-codegen/pkg/middleware"
+       "github.com/deepmap/oapi-codegen/pkg/testutil"
+       echomiddleware "github.com/labstack/echo/v4/middleware"
+       "github.com/stretchr/testify/assert"
+       "github.com/stretchr/testify/mock"
+)
+
+func TestOnboardInvoker(t *testing.T) {
+       var err error
+       apiId := "apiId"
+       aefId := "aefId"
+       apiRegisterMock := publishmocks.APIRegister{}
+       apiRegisterMock.On("AreAPIsRegistered", mock.Anything).Return(true)
+       invokerUnderTest, requestHandler := getEcho(&apiRegisterMock)
+
+       description := "description"
+       domainName := "domain"
+       var protocol publishserviceapi.Protocol = "HTTP_1_1"
+       var apiList invokermanagementapi.APIList = []publishserviceapi.ServiceAPIDescription{
+               {
+                       ApiId:       &apiId,
+                       ApiName:     "api",
+                       Description: &description,
+                       AefProfiles: &[]publishserviceapi.AefProfile{
+                               {
+                                       AefId:      aefId,
+                                       DomainName: &domainName,
+                                       Protocol:   &protocol,
+                                       Versions: []publishserviceapi.Version{
+                                               {
+                                                       ApiVersion: "v1",
+                                                       Resources: &[]publishserviceapi.Resource{
+                                                               {
+                                                                       ResourceName: "app",
+                                                                       CommType:     "REQUEST_RESPONSE",
+                                                                       Uri:          "uri",
+                                                                       Operations: &[]publishserviceapi.Operation{
+                                                                               "POST",
+                                                                       },
+                                                               },
+                                                       },
+                                               },
+                                       },
+                               },
+                       },
+               },
+       }
+       invokerInfo := "invoker a"
+       newInvoker := invokermanagementapi.APIInvokerEnrolmentDetails{
+               ApiInvokerInformation:   &invokerInfo,
+               NotificationDestination: "url",
+               OnboardingInformation: invokermanagementapi.OnboardingInformation{
+                       ApiInvokerPublicKey: "key",
+               },
+               ApiList: &apiList,
+       }
+
+       // Onboard a valid invoker
+       result := testutil.NewRequest().Post("/onboardedInvokers").WithJsonBody(newInvoker).Go(t, requestHandler)
+
+       assert.Equal(t, http.StatusCreated, result.Code())
+       var resultInvoker invokermanagementapi.APIInvokerEnrolmentDetails
+       err = result.UnmarshalBodyToObject(&resultInvoker)
+       assert.NoError(t, err, "error unmarshaling response")
+       assert.Equal(t, "api_invoker_id_invoker_a", *resultInvoker.ApiInvokerId)
+       assert.Equal(t, newInvoker.NotificationDestination, resultInvoker.NotificationDestination)
+       assert.Equal(t, newInvoker.OnboardingInformation.ApiInvokerPublicKey, resultInvoker.OnboardingInformation.ApiInvokerPublicKey)
+       assert.Equal(t, "onboarding_secret_invoker_a", *resultInvoker.OnboardingInformation.OnboardingSecret)
+       assert.Equal(t, "http://example.com/onboardedInvokers/"+*resultInvoker.ApiInvokerId, result.Recorder.Header().Get(echo.HeaderLocation))
+       assert.True(t, invokerUnderTest.IsInvokerRegistered("api_invoker_id_invoker_a"))
+       assert.True(t, invokerUnderTest.VerifyInvokerSecret("api_invoker_id_invoker_a", "onboarding_secret_invoker_a"))
+       apiRegisterMock.AssertCalled(t, "AreAPIsRegistered", mock.Anything)
+
+       // Onboard an invoker missing required NotificationDestination, should get 400 with problem details
+       invalidInvoker := invokermanagementapi.APIInvokerEnrolmentDetails{
+               OnboardingInformation: invokermanagementapi.OnboardingInformation{
+                       ApiInvokerPublicKey: "key",
+               },
+       }
+       result = testutil.NewRequest().Post("/onboardedInvokers").WithJsonBody(invalidInvoker).Go(t, requestHandler)
+
+       assert.Equal(t, http.StatusBadRequest, result.Code())
+       var problemDetails common29122.ProblemDetails
+       err = result.UnmarshalBodyToObject(&problemDetails)
+       assert.NoError(t, err, "error unmarshaling response")
+       badRequest := 400
+       assert.Equal(t, &badRequest, problemDetails.Status)
+       errMsg := "Invoker missing required NotificationDestination"
+       assert.Equal(t, &errMsg, problemDetails.Cause)
+
+       // Onboard an invoker missing required OnboardingInformation.ApiInvokerPublicKey, should get 400 with problem details
+       invalidInvoker = invokermanagementapi.APIInvokerEnrolmentDetails{
+               NotificationDestination: "url",
+       }
+
+       result = testutil.NewRequest().Post("/onboardedInvokers").WithJsonBody(invalidInvoker).Go(t, requestHandler)
+
+       assert.Equal(t, http.StatusBadRequest, result.Code())
+       err = result.UnmarshalBodyToObject(&problemDetails)
+       assert.NoError(t, err, "error unmarshaling response")
+       assert.Equal(t, &badRequest, problemDetails.Status)
+       errMsg = "Invoker missing required OnboardingInformation.ApiInvokerPublicKey"
+       assert.Equal(t, &errMsg, problemDetails.Cause)
+}
+
+func TestDeleteInvoker(t *testing.T) {
+       _, requestHandler := getEcho(nil)
+
+       newInvoker := invokermanagementapi.APIInvokerEnrolmentDetails{
+               NotificationDestination: "url",
+               OnboardingInformation: invokermanagementapi.OnboardingInformation{
+                       ApiInvokerPublicKey: "key",
+               },
+       }
+
+       // Onboard an invoker
+       result := testutil.NewRequest().Post("/onboardedInvokers").WithJsonBody(newInvoker).Go(t, requestHandler)
+       var resultInvoker invokermanagementapi.APIInvokerEnrolmentDetails
+       result.UnmarshalBodyToObject(&resultInvoker)
+
+       invokerUrl := result.Recorder.Header().Get(echo.HeaderLocation)
+
+       // Delete the invoker
+       result = testutil.NewRequest().Delete(invokerUrl).Go(t, requestHandler)
+
+       assert.Equal(t, http.StatusNoContent, result.Code())
+}
+
+func TestUpdateInvoker(t *testing.T) {
+       _, requestHandler := getEcho(nil)
+
+       newInvoker := invokermanagementapi.APIInvokerEnrolmentDetails{
+               NotificationDestination: "url",
+               OnboardingInformation: invokermanagementapi.OnboardingInformation{
+                       ApiInvokerPublicKey: "key",
+               },
+       }
+
+       // Onboard an invoker
+       result := testutil.NewRequest().Post("/onboardedInvokers").WithJsonBody(newInvoker).Go(t, requestHandler)
+       var resultInvoker invokermanagementapi.APIInvokerEnrolmentDetails
+       result.UnmarshalBodyToObject(&resultInvoker)
+
+       invokerId := resultInvoker.ApiInvokerId
+       invokerUrl := result.Recorder.Header().Get(echo.HeaderLocation)
+
+       // Update the invoker with valid invoker, should return 200 with invoker details
+       result = testutil.NewRequest().Put(invokerUrl).WithJsonBody(resultInvoker).Go(t, requestHandler)
+
+       assert.Equal(t, http.StatusOK, result.Code())
+       err := result.UnmarshalBodyToObject(&resultInvoker)
+       assert.NoError(t, err, "error unmarshaling response")
+       assert.Equal(t, invokerId, resultInvoker.ApiInvokerId)
+       assert.Equal(t, newInvoker.NotificationDestination, resultInvoker.NotificationDestination)
+       assert.Equal(t, newInvoker.OnboardingInformation.ApiInvokerPublicKey, resultInvoker.OnboardingInformation.ApiInvokerPublicKey)
+
+       // Update with an invoker missing required NotificationDestination, should get 400 with problem details
+       validOnboardingInfo := invokermanagementapi.OnboardingInformation{
+               ApiInvokerPublicKey: "key",
+       }
+       invalidInvoker := invokermanagementapi.APIInvokerEnrolmentDetails{
+               ApiInvokerId:          invokerId,
+               OnboardingInformation: validOnboardingInfo,
+       }
+       result = testutil.NewRequest().Put(invokerUrl).WithJsonBody(invalidInvoker).Go(t, requestHandler)
+
+       assert.Equal(t, http.StatusBadRequest, result.Code())
+       var problemDetails common29122.ProblemDetails
+       err = result.UnmarshalBodyToObject(&problemDetails)
+       assert.NoError(t, err, "error unmarshaling response")
+       badRequest := 400
+       assert.Equal(t, &badRequest, problemDetails.Status)
+       errMsg := "Invoker missing required NotificationDestination"
+       assert.Equal(t, &errMsg, problemDetails.Cause)
+
+       // Update with an invoker missing required OnboardingInformation.ApiInvokerPublicKey, should get 400 with problem details
+       invalidInvoker.NotificationDestination = "url"
+       invalidInvoker.OnboardingInformation = invokermanagementapi.OnboardingInformation{}
+       result = testutil.NewRequest().Put(invokerUrl).WithJsonBody(invalidInvoker).Go(t, requestHandler)
+
+       assert.Equal(t, http.StatusBadRequest, result.Code())
+       err = result.UnmarshalBodyToObject(&problemDetails)
+       assert.NoError(t, err, "error unmarshaling response")
+       assert.Equal(t, &badRequest, problemDetails.Status)
+       errMsg = "Invoker missing required OnboardingInformation.ApiInvokerPublicKey"
+       assert.Equal(t, &errMsg, problemDetails.Cause)
+
+       // Update with an invoker with other ApiInvokerId than the one provided in the URL, should get 400 with problem details
+       invalidId := "1"
+       invalidInvoker.ApiInvokerId = &invalidId
+       invalidInvoker.OnboardingInformation = validOnboardingInfo
+       result = testutil.NewRequest().Put(invokerUrl).WithJsonBody(invalidInvoker).Go(t, requestHandler)
+
+       assert.Equal(t, http.StatusBadRequest, result.Code())
+       err = result.UnmarshalBodyToObject(&problemDetails)
+       assert.NoError(t, err, "error unmarshaling response")
+       assert.Equal(t, &badRequest, problemDetails.Status)
+       errMsg = "Invoker ApiInvokerId not matching"
+       assert.Equal(t, &errMsg, problemDetails.Cause)
+
+       // Update an invoker that has not been onboarded, shold get 404 with problem details
+       missingId := "1"
+       newInvoker.ApiInvokerId = &missingId
+       result = testutil.NewRequest().Put("/onboardedInvokers/"+missingId).WithJsonBody(newInvoker).Go(t, requestHandler)
+
+       assert.Equal(t, http.StatusNotFound, result.Code())
+       err = result.UnmarshalBodyToObject(&problemDetails)
+       assert.NoError(t, err, "error unmarshaling response")
+       notFound := 404
+       assert.Equal(t, &notFound, problemDetails.Status)
+       errMsg = "The invoker to update has not been onboarded"
+       assert.Equal(t, &errMsg, problemDetails.Cause)
+
+}
+
+func getEcho(apiRegister publishservice.APIRegister) (*InvokerManager, *echo.Echo) {
+       swagger, err := invokermanagementapi.GetSwagger()
+       if err != nil {
+               fmt.Fprintf(os.Stderr, "Error loading swagger spec\n: %s", err)
+               os.Exit(1)
+       }
+
+       swagger.Servers = nil
+
+       im := NewInvokerManager(apiRegister)
+
+       e := echo.New()
+       e.Use(echomiddleware.Logger())
+       e.Use(middleware.OapiRequestValidator(swagger))
+
+       invokermanagementapi.RegisterHandlers(e, im)
+       return im, e
+}
diff --git a/internal/invokermanagement/mocks/InvokerRegister.go b/internal/invokermanagement/mocks/InvokerRegister.go
new file mode 100644 (file)
index 0000000..3eb317a
--- /dev/null
@@ -0,0 +1,53 @@
+// Code generated by mockery v2.14.0. DO NOT EDIT.
+
+package mocks
+
+import mock "github.com/stretchr/testify/mock"
+
+// InvokerRegister is an autogenerated mock type for the InvokerRegister type
+type InvokerRegister struct {
+       mock.Mock
+}
+
+// IsInvokerRegistered provides a mock function with given fields: invokerId
+func (_m *InvokerRegister) IsInvokerRegistered(invokerId string) bool {
+       ret := _m.Called(invokerId)
+
+       var r0 bool
+       if rf, ok := ret.Get(0).(func(string) bool); ok {
+               r0 = rf(invokerId)
+       } else {
+               r0 = ret.Get(0).(bool)
+       }
+
+       return r0
+}
+
+// VerifyInvokerSecret provides a mock function with given fields: invokerId, secret
+func (_m *InvokerRegister) VerifyInvokerSecret(invokerId string, secret string) bool {
+       ret := _m.Called(invokerId, secret)
+
+       var r0 bool
+       if rf, ok := ret.Get(0).(func(string, string) bool); ok {
+               r0 = rf(invokerId, secret)
+       } else {
+               r0 = ret.Get(0).(bool)
+       }
+
+       return r0
+}
+
+type mockConstructorTestingTNewInvokerRegister interface {
+       mock.TestingT
+       Cleanup(func())
+}
+
+// NewInvokerRegister creates a new instance of InvokerRegister. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewInvokerRegister(t mockConstructorTestingTNewInvokerRegister) *InvokerRegister {
+       mock := &InvokerRegister{}
+       mock.Mock.Test(t)
+
+       t.Cleanup(func() { mock.AssertExpectations(t) })
+
+       return mock
+}
diff --git a/internal/providermanagement/mocks/ServiceRegister.go b/internal/providermanagement/mocks/ServiceRegister.go
new file mode 100644 (file)
index 0000000..b97a0f4
--- /dev/null
@@ -0,0 +1,39 @@
+// Code generated by mockery v2.14.0. DO NOT EDIT.
+
+package mocks
+
+import mock "github.com/stretchr/testify/mock"
+
+// ServiceRegister is an autogenerated mock type for the ServiceRegister type
+type ServiceRegister struct {
+       mock.Mock
+}
+
+// IsFunctionRegistered provides a mock function with given fields: aefId
+func (_m *ServiceRegister) IsFunctionRegistered(aefId string) bool {
+       ret := _m.Called(aefId)
+
+       var r0 bool
+       if rf, ok := ret.Get(0).(func(string) bool); ok {
+               r0 = rf(aefId)
+       } else {
+               r0 = ret.Get(0).(bool)
+       }
+
+       return r0
+}
+
+type mockConstructorTestingTNewServiceRegister interface {
+       mock.TestingT
+       Cleanup(func())
+}
+
+// NewServiceRegister creates a new instance of ServiceRegister. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewServiceRegister(t mockConstructorTestingTNewServiceRegister) *ServiceRegister {
+       mock := &ServiceRegister{}
+       mock.Mock.Test(t)
+
+       t.Cleanup(func() { mock.AssertExpectations(t) })
+
+       return mock
+}
diff --git a/internal/providermanagement/providermanagement.go b/internal/providermanagement/providermanagement.go
new file mode 100644 (file)
index 0000000..89430ee
--- /dev/null
@@ -0,0 +1,186 @@
+// -
+//   ========================LICENSE_START=================================
+//   O-RAN-SC
+//   %%
+//   Copyright (C) 2022: Nordix Foundation
+//   %%
+//   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.
+//   ========================LICENSE_END===================================
+//
+
+package providermanagement
+
+import (
+       "net/http"
+       "path"
+       "strings"
+       "sync"
+
+       "github.com/labstack/echo/v4"
+
+       "oransc.org/nonrtric/sme/internal/common29122"
+       provapi "oransc.org/nonrtric/sme/internal/providermanagementapi"
+
+       log "github.com/sirupsen/logrus"
+)
+
+//go:generate mockery --name ServiceRegister
+type ServiceRegister interface {
+       IsFunctionRegistered(aefId string) bool
+}
+
+type ProviderManager struct {
+       onboardedProviders map[string]provapi.APIProviderEnrolmentDetails
+       lock               sync.Mutex
+}
+
+func NewProviderManager() *ProviderManager {
+       return &ProviderManager{
+               onboardedProviders: make(map[string]provapi.APIProviderEnrolmentDetails),
+       }
+}
+
+func (pm *ProviderManager) IsFunctionRegistered(aefId string) bool {
+       registered := false
+out:
+       for _, provider := range pm.onboardedProviders {
+               for _, registeredFunc := range *provider.ApiProvFuncs {
+                       if *registeredFunc.ApiProvFuncId == aefId {
+                               registered = true
+                               break out
+                       }
+               }
+       }
+
+       return registered
+}
+
+func (pm *ProviderManager) PostRegistrations(ctx echo.Context) error {
+       var newProvider provapi.APIProviderEnrolmentDetails
+       err := ctx.Bind(&newProvider)
+       if err != nil {
+               return sendCoreError(ctx, http.StatusBadRequest, "Invalid format for provider")
+       }
+
+       if newProvider.ApiProvDomInfo == nil || *newProvider.ApiProvDomInfo == "" {
+               return sendCoreError(ctx, http.StatusBadRequest, "Provider missing required ApiProvDomInfo")
+       }
+
+       pm.lock.Lock()
+       defer pm.lock.Unlock()
+
+       newProvider.ApiProvDomId = pm.getDomainId(newProvider.ApiProvDomInfo)
+
+       pm.registerFunctions(newProvider.ApiProvFuncs)
+       pm.onboardedProviders[*newProvider.ApiProvDomId] = newProvider
+
+       uri := ctx.Request().Host + ctx.Request().URL.String()
+       ctx.Response().Header().Set(echo.HeaderLocation, ctx.Scheme()+`://`+path.Join(uri, *newProvider.ApiProvDomId))
+       err = ctx.JSON(http.StatusCreated, newProvider)
+       if err != nil {
+               // Something really bad happened, tell Echo that our handler failed
+               return err
+       }
+
+       return nil
+}
+
+func (pm *ProviderManager) DeleteRegistrationsRegistrationId(ctx echo.Context, registrationId string) error {
+       pm.lock.Lock()
+       defer pm.lock.Unlock()
+
+       log.Debug(pm.onboardedProviders)
+       if _, ok := pm.onboardedProviders[registrationId]; ok {
+               log.Debug("Deleting provider", registrationId)
+               delete(pm.onboardedProviders, registrationId)
+       }
+
+       return ctx.NoContent(http.StatusNoContent)
+}
+
+func (pm *ProviderManager) PutRegistrationsRegistrationId(ctx echo.Context, registrationId string) error {
+       registeredProvider, ok := pm.onboardedProviders[registrationId]
+       if !ok {
+               return sendCoreError(ctx, http.StatusBadRequest, "Provider must be onboarded before updating it")
+
+       }
+
+       var updatedProvider provapi.APIProviderEnrolmentDetails
+       err := ctx.Bind(&updatedProvider)
+       if err != nil {
+               return sendCoreError(ctx, http.StatusBadRequest, "Invalid format for provider")
+       }
+
+       for _, function := range *updatedProvider.ApiProvFuncs {
+               if function.ApiProvFuncId == nil {
+                       function.ApiProvFuncId = pm.getFuncId(function.ApiProvFuncRole, function.ApiProvFuncInfo)
+                       registeredFuncs := *registeredProvider.ApiProvFuncs
+                       newFuncs := append(registeredFuncs, function)
+                       registeredProvider.ApiProvFuncs = &newFuncs
+                       pm.onboardedProviders[*registeredProvider.ApiProvDomId] = registeredProvider
+               }
+       }
+
+       err = ctx.JSON(http.StatusOK, registeredProvider)
+       if err != nil {
+               // Something really bad happened, tell Echo that our handler failed
+               return err
+       }
+
+       return nil
+}
+
+func (pm *ProviderManager) ModifyIndApiProviderEnrolment(ctx echo.Context, registrationId string) error {
+       return ctx.NoContent(http.StatusNotImplemented)
+}
+
+func (pm *ProviderManager) registerFunctions(provFuncs *[]provapi.APIProviderFunctionDetails) {
+       if provFuncs == nil {
+               return
+       }
+       for i, provFunc := range *provFuncs {
+               (*provFuncs)[i].ApiProvFuncId = pm.getFuncId(provFunc.ApiProvFuncRole, provFunc.ApiProvFuncInfo)
+       }
+}
+
+func (pm *ProviderManager) getDomainId(domainInfo *string) *string {
+       idAsString := "domain_id_" + strings.ReplaceAll(*domainInfo, " ", "_")
+       return &idAsString
+}
+
+func (pm *ProviderManager) getFuncId(role provapi.ApiProviderFuncRole, funcInfo *string) *string {
+       var idPrefix string
+       switch role {
+       case provapi.ApiProviderFuncRoleAPF:
+               idPrefix = "APF_id_"
+       case provapi.ApiProviderFuncRoleAMF:
+               idPrefix = "AMF_id_"
+       case provapi.ApiProviderFuncRoleAEF:
+               idPrefix = "AEF_id_"
+       default:
+               idPrefix = "function_id_"
+       }
+       idAsString := idPrefix + strings.ReplaceAll(*funcInfo, " ", "_")
+       return &idAsString
+}
+
+// This function wraps sending of an error in the Error format, and
+// handling the failure to marshal that.
+func sendCoreError(ctx echo.Context, code int, message string) error {
+       pd := common29122.ProblemDetails{
+               Cause:  &message,
+               Status: &code,
+       }
+       err := ctx.JSON(code, pd)
+       return err
+}
diff --git a/internal/providermanagement/providermanagement_test.go b/internal/providermanagement/providermanagement_test.go
new file mode 100644 (file)
index 0000000..e88eeb9
--- /dev/null
@@ -0,0 +1,147 @@
+// -
+//   ========================LICENSE_START=================================
+//   O-RAN-SC
+//   %%
+//   Copyright (C) 2022: Nordix Foundation
+//   %%
+//   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.
+//   ========================LICENSE_END===================================
+//
+
+package providermanagement
+
+import (
+       "fmt"
+       "net/http"
+       "os"
+       "testing"
+
+       "github.com/labstack/echo/v4"
+
+       "oransc.org/nonrtric/sme/internal/common29122"
+       provapi "oransc.org/nonrtric/sme/internal/providermanagementapi"
+
+       "github.com/deepmap/oapi-codegen/pkg/middleware"
+       "github.com/deepmap/oapi-codegen/pkg/testutil"
+       echomiddleware "github.com/labstack/echo/v4/middleware"
+       "github.com/stretchr/testify/assert"
+)
+
+func TestProviderHandlingSuccessfully(t *testing.T) {
+       managerUnderTest, requestHandler := getEcho()
+
+       domainInfo := "rApp domain"
+       funcInfoAPF := "rApp as APF"
+       funcInfoAMF := "rApp as AMF"
+       funcInfoAEF := "rApp as AEF"
+       testFuncs := []provapi.APIProviderFunctionDetails{
+               {
+                       ApiProvFuncInfo: &funcInfoAPF,
+                       ApiProvFuncRole: provapi.ApiProviderFuncRoleAPF,
+               },
+               {
+                       ApiProvFuncInfo: &funcInfoAMF,
+                       ApiProvFuncRole: provapi.ApiProviderFuncRoleAMF,
+               },
+               {
+                       ApiProvFuncInfo: &funcInfoAEF,
+                       ApiProvFuncRole: provapi.ApiProviderFuncRoleAEF,
+               },
+       }
+       newProvider := provapi.APIProviderEnrolmentDetails{
+               ApiProvDomInfo: &domainInfo,
+               ApiProvFuncs:   &testFuncs,
+       }
+
+       // Register a valid provider
+       result := testutil.NewRequest().Post("/registrations").WithJsonBody(newProvider).Go(t, requestHandler)
+
+       domainID := "domain_id_rApp_domain"
+       funcIdAPF := "APF_id_rApp_as_APF"
+       funcIdAMF := "AMF_id_rApp_as_AMF"
+       funcIdAEF := "AEF_id_rApp_as_AEF"
+       assert.Equal(t, http.StatusCreated, result.Code())
+       var resultProvider provapi.APIProviderEnrolmentDetails
+       err := result.UnmarshalBodyToObject(&resultProvider)
+       assert.NoError(t, err, "error unmarshaling response")
+       assert.Equal(t, *resultProvider.ApiProvDomId, domainID)
+       assert.Equal(t, *(*resultProvider.ApiProvFuncs)[0].ApiProvFuncId, funcIdAPF)
+       assert.Equal(t, *(*resultProvider.ApiProvFuncs)[1].ApiProvFuncId, funcIdAMF)
+       assert.Equal(t, *(*resultProvider.ApiProvFuncs)[2].ApiProvFuncId, funcIdAEF)
+       assert.Empty(t, resultProvider.FailReason)
+       assert.Equal(t, "http://example.com/registrations/"+*resultProvider.ApiProvDomId, result.Recorder.Header().Get(echo.HeaderLocation))
+       assert.True(t, managerUnderTest.IsFunctionRegistered("APF_id_rApp_as_APF"))
+
+       // Update the provider
+       newProvider.ApiProvDomId = &domainID
+       (*newProvider.ApiProvFuncs)[0].ApiProvFuncId = &funcIdAPF
+       (*newProvider.ApiProvFuncs)[1].ApiProvFuncId = &funcIdAMF
+       (*newProvider.ApiProvFuncs)[2].ApiProvFuncId = &funcIdAEF
+       newFuncInfoAEF := "new func as AEF"
+       testFuncs = append(testFuncs, provapi.APIProviderFunctionDetails{
+               ApiProvFuncInfo: &newFuncInfoAEF,
+               ApiProvFuncRole: "AEF",
+       })
+
+       result = testutil.NewRequest().Put("/registrations/"+domainID).WithJsonBody(newProvider).Go(t, requestHandler)
+
+       assert.Equal(t, http.StatusOK, result.Code())
+       err = result.UnmarshalBodyToObject(&resultProvider)
+       assert.NoError(t, err, "error unmarshaling response")
+       assert.Equal(t, *(*resultProvider.ApiProvFuncs)[3].ApiProvFuncId, "AEF_id_new_func_as_AEF")
+       assert.Empty(t, resultProvider.FailReason)
+       assert.True(t, managerUnderTest.IsFunctionRegistered("AEF_id_new_func_as_AEF"))
+
+       // Delete the provider
+       result = testutil.NewRequest().Delete("/registrations/"+*resultProvider.ApiProvDomId).Go(t, requestHandler)
+
+       assert.Equal(t, http.StatusNoContent, result.Code())
+       assert.False(t, managerUnderTest.IsFunctionRegistered("APF_id_rApp_as_APF"))
+}
+
+func TestProviderHandlingValidation(t *testing.T) {
+       _, requestHandler := getEcho()
+
+       newProvider := provapi.APIProviderEnrolmentDetails{}
+
+       // Register a valid provider
+       result := testutil.NewRequest().Post("/registrations").WithJsonBody(newProvider).Go(t, requestHandler)
+
+       assert.Equal(t, http.StatusBadRequest, result.Code())
+       var problemDetails common29122.ProblemDetails
+       err := result.UnmarshalBodyToObject(&problemDetails)
+       assert.NoError(t, err, "error unmarshaling response")
+       badRequest := 400
+       assert.Equal(t, &badRequest, problemDetails.Status)
+       errMsg := "Provider missing required ApiProvDomInfo"
+       assert.Equal(t, &errMsg, problemDetails.Cause)
+}
+
+func getEcho() (*ProviderManager, *echo.Echo) {
+       swagger, err := provapi.GetSwagger()
+       if err != nil {
+               fmt.Fprintf(os.Stderr, "Error loading swagger spec\n: %s", err)
+               os.Exit(1)
+       }
+
+       swagger.Servers = nil
+
+       pm := NewProviderManager()
+
+       e := echo.New()
+       e.Use(echomiddleware.Logger())
+       e.Use(middleware.OapiRequestValidator(swagger))
+
+       provapi.RegisterHandlers(e, pm)
+       return pm, e
+}
diff --git a/internal/publishservice/mocks/APIRegister.go b/internal/publishservice/mocks/APIRegister.go
new file mode 100644 (file)
index 0000000..3ec7699
--- /dev/null
@@ -0,0 +1,73 @@
+// Code generated by mockery v2.14.0. DO NOT EDIT.
+
+package mocks
+
+import (
+       mock "github.com/stretchr/testify/mock"
+
+       publishserviceapi "oransc.org/nonrtric/sme/internal/publishserviceapi"
+)
+
+// APIRegister is an autogenerated mock type for the APIRegister type
+type APIRegister struct {
+       mock.Mock
+}
+
+// AreAPIsRegistered provides a mock function with given fields: serviceDescriptions
+func (_m *APIRegister) AreAPIsRegistered(serviceDescriptions *[]publishserviceapi.ServiceAPIDescription) bool {
+       ret := _m.Called(serviceDescriptions)
+
+       var r0 bool
+       if rf, ok := ret.Get(0).(func(*[]publishserviceapi.ServiceAPIDescription) bool); ok {
+               r0 = rf(serviceDescriptions)
+       } else {
+               r0 = ret.Get(0).(bool)
+       }
+
+       return r0
+}
+
+// GetAPIs provides a mock function with given fields:
+func (_m *APIRegister) GetAPIs() *[]publishserviceapi.ServiceAPIDescription {
+       ret := _m.Called()
+
+       var r0 *[]publishserviceapi.ServiceAPIDescription
+       if rf, ok := ret.Get(0).(func() *[]publishserviceapi.ServiceAPIDescription); ok {
+               r0 = rf()
+       } else {
+               if ret.Get(0) != nil {
+                       r0 = ret.Get(0).(*[]publishserviceapi.ServiceAPIDescription)
+               }
+       }
+
+       return r0
+}
+
+// IsAPIRegistered provides a mock function with given fields: aefId, path
+func (_m *APIRegister) IsAPIRegistered(aefId string, path string) bool {
+       ret := _m.Called(aefId, path)
+
+       var r0 bool
+       if rf, ok := ret.Get(0).(func(string, string) bool); ok {
+               r0 = rf(aefId, path)
+       } else {
+               r0 = ret.Get(0).(bool)
+       }
+
+       return r0
+}
+
+type mockConstructorTestingTNewAPIRegister interface {
+       mock.TestingT
+       Cleanup(func())
+}
+
+// NewAPIRegister creates a new instance of APIRegister. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewAPIRegister(t mockConstructorTestingTNewAPIRegister) *APIRegister {
+       mock := &APIRegister{}
+       mock.Mock.Test(t)
+
+       t.Cleanup(func() { mock.AssertExpectations(t) })
+
+       return mock
+}
diff --git a/internal/publishservice/publishservice.go b/internal/publishservice/publishservice.go
new file mode 100644 (file)
index 0000000..cdf11dd
--- /dev/null
@@ -0,0 +1,221 @@
+// -
+//   ========================LICENSE_START=================================
+//   O-RAN-SC
+//   %%
+//   Copyright (C) 2022: Nordix Foundation
+//   %%
+//   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.
+//   ========================LICENSE_END===================================
+//
+
+package publishservice
+
+import (
+       "net/http"
+       "path"
+       "strings"
+       "sync"
+
+       "github.com/labstack/echo/v4"
+
+       "oransc.org/nonrtric/sme/internal/common29122"
+       "oransc.org/nonrtric/sme/internal/publishserviceapi"
+
+       "oransc.org/nonrtric/sme/internal/helmmanagement"
+       "oransc.org/nonrtric/sme/internal/providermanagement"
+
+       log "github.com/sirupsen/logrus"
+)
+
+//go:generate mockery --name APIRegister
+type APIRegister interface {
+       AreAPIsRegistered(serviceDescriptions *[]publishserviceapi.ServiceAPIDescription) bool
+       GetAPIs() *[]publishserviceapi.ServiceAPIDescription
+       IsAPIRegistered(aefId, path string) bool
+}
+
+type PublishService struct {
+       publishedServices map[string]publishserviceapi.ServiceAPIDescription
+       serviceRegister   providermanagement.ServiceRegister
+       helmManager       helmmanagement.HelmManager
+       lock              sync.Mutex
+}
+
+func NewPublishService(serviceRegister providermanagement.ServiceRegister, hm helmmanagement.HelmManager) *PublishService {
+       return &PublishService{
+               helmManager:       hm,
+               publishedServices: make(map[string]publishserviceapi.ServiceAPIDescription),
+               serviceRegister:   serviceRegister,
+       }
+}
+
+func (ps *PublishService) AreAPIsRegistered(serviceDescriptions *[]publishserviceapi.ServiceAPIDescription) bool {
+       ps.lock.Lock()
+       defer ps.lock.Unlock()
+
+       allRegistered := true
+       if serviceDescriptions != nil {
+       out:
+               for _, newApi := range *serviceDescriptions {
+                       registeredApi, ok := ps.publishedServices[*newApi.ApiId]
+                       if ok {
+                               if !ps.areProfilesRegistered(newApi.AefProfiles, registeredApi.AefProfiles) {
+                                       allRegistered = false
+                                       break out
+                               }
+                       } else {
+                               allRegistered = false
+                               break out
+                       }
+               }
+       }
+       return allRegistered
+}
+
+func (ps *PublishService) areProfilesRegistered(newProfiles *[]publishserviceapi.AefProfile, registeredProfiles *[]publishserviceapi.AefProfile) bool {
+       allRegistered := true
+       if newProfiles != nil && registeredProfiles != nil {
+       out:
+               for _, newProfile := range *newProfiles {
+                       for _, registeredProfile := range *registeredProfiles {
+                               if newProfile.AefId == registeredProfile.AefId {
+                                       break
+                               }
+                               allRegistered = false
+                               break out
+                       }
+               }
+       } else if registeredProfiles == nil {
+               allRegistered = false
+       }
+       return allRegistered
+}
+
+func (ps *PublishService) GetAPIs() *[]publishserviceapi.ServiceAPIDescription {
+       ps.lock.Lock()
+       defer ps.lock.Unlock()
+
+       apis := []publishserviceapi.ServiceAPIDescription{}
+       for _, service := range ps.publishedServices {
+               apis = append(apis, service)
+       }
+       return &apis
+}
+
+func (ps *PublishService) IsAPIRegistered(aefId, path string) bool {
+       ps.lock.Lock()
+       defer ps.lock.Unlock()
+
+       registered := false
+out:
+       for _, service := range ps.publishedServices {
+               if service.ApiName == path {
+                       for _, profile := range *service.AefProfiles {
+                               if profile.AefId == aefId {
+                                       registered = true
+                                       break out
+                               }
+                       }
+               }
+       }
+       return registered
+}
+
+func (ps *PublishService) GetApfIdServiceApis(ctx echo.Context, apfId publishserviceapi.ApfId) error {
+       return ctx.NoContent(http.StatusNotImplemented)
+}
+
+func (ps *PublishService) PostApfIdServiceApis(ctx echo.Context, apfId publishserviceapi.ApfId) error {
+       var newServiceAPIDescription publishserviceapi.ServiceAPIDescription
+       err := ctx.Bind(&newServiceAPIDescription)
+       if err != nil {
+               return sendCoreError(ctx, http.StatusBadRequest, "Invalid format for service")
+       }
+
+       ps.lock.Lock()
+       defer ps.lock.Unlock()
+
+       for _, profile := range *newServiceAPIDescription.AefProfiles {
+               if !ps.serviceRegister.IsFunctionRegistered(profile.AefId) {
+                       return sendCoreError(ctx, http.StatusNotFound, "Function not registered, "+profile.AefId)
+               }
+       }
+
+       newId := "api_id_" + newServiceAPIDescription.ApiName
+       newServiceAPIDescription.ApiId = &newId
+       info := strings.Split(*newServiceAPIDescription.Description, ",")
+       if len(info) == 5 {
+               err = ps.helmManager.InstallHelmChart(info[1], info[2], info[3], info[4])
+               if err != nil {
+                       return sendCoreError(ctx, http.StatusBadRequest, "Unable to install Helm chart due to: "+err.Error())
+               }
+               log.Info("Installed service: ", newId)
+       }
+       ps.publishedServices[*newServiceAPIDescription.ApiId] = newServiceAPIDescription
+
+       uri := ctx.Request().Host + ctx.Request().URL.String()
+       ctx.Response().Header().Set(echo.HeaderLocation, ctx.Scheme()+`://`+path.Join(uri, *newServiceAPIDescription.ApiId))
+       err = ctx.JSON(http.StatusCreated, newServiceAPIDescription)
+       if err != nil {
+               // Something really bad happened, tell Echo that our handler failed
+               return err
+       }
+
+       return nil
+}
+
+func (ps *PublishService) DeleteApfIdServiceApisServiceApiId(ctx echo.Context, apfId publishserviceapi.ApfId, serviceApiId publishserviceapi.ServiceApiId) error {
+       serviceDescription, ok := ps.publishedServices[string(serviceApiId)]
+       if ok {
+               info := strings.Split(*serviceDescription.Description, ",")
+               if len(info) == 5 {
+                       ps.helmManager.UninstallHelmChart(info[1], info[3])
+                       log.Info("Deleted service: ", serviceApiId)
+               }
+               delete(ps.publishedServices, string(serviceApiId))
+       }
+       return ctx.NoContent(http.StatusNoContent)
+}
+
+func (ps *PublishService) GetApfIdServiceApisServiceApiId(ctx echo.Context, apfId publishserviceapi.ApfId, serviceApiId publishserviceapi.ServiceApiId) error {
+       serviceDescription, ok := ps.publishedServices[string(serviceApiId)]
+       if ok {
+               err := ctx.JSON(http.StatusOK, serviceDescription)
+               if err != nil {
+                       // Something really bad happened, tell Echo that our handler failed
+                       return err
+               }
+
+               return nil
+       }
+       return ctx.NoContent(http.StatusNotFound)
+}
+
+func (ps *PublishService) ModifyIndAPFPubAPI(ctx echo.Context, apfId publishserviceapi.ApfId, serviceApiId publishserviceapi.ServiceApiId) error {
+       return ctx.NoContent(http.StatusNotImplemented)
+}
+
+func (ps *PublishService) PutApfIdServiceApisServiceApiId(ctx echo.Context, apfId publishserviceapi.ApfId, serviceApiId publishserviceapi.ServiceApiId) error {
+       return ctx.NoContent(http.StatusNotImplemented)
+}
+
+// This function wraps sending of an error in the Error format, and
+// handling the failure to marshal that.
+func sendCoreError(ctx echo.Context, code int, message string) error {
+       pd := common29122.ProblemDetails{
+               Cause:  &message,
+               Status: &code,
+       }
+       err := ctx.JSON(code, pd)
+       return err
+}
diff --git a/internal/publishservice/publishservice_test.go b/internal/publishservice/publishservice_test.go
new file mode 100644 (file)
index 0000000..b5f601d
--- /dev/null
@@ -0,0 +1,146 @@
+// -
+//   ========================LICENSE_START=================================
+//   O-RAN-SC
+//   %%
+//   Copyright (C) 2022: Nordix Foundation
+//   %%
+//   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.
+//   ========================LICENSE_END===================================
+//
+
+package publishservice
+
+import (
+       "fmt"
+       "net/http"
+       "os"
+       "testing"
+
+       "oransc.org/nonrtric/sme/internal/providermanagement"
+
+       "github.com/labstack/echo/v4"
+
+       publishapi "oransc.org/nonrtric/sme/internal/publishserviceapi"
+
+       "oransc.org/nonrtric/sme/internal/helmmanagement"
+       helmMocks "oransc.org/nonrtric/sme/internal/helmmanagement/mocks"
+       serviceMocks "oransc.org/nonrtric/sme/internal/providermanagement/mocks"
+
+       "github.com/deepmap/oapi-codegen/pkg/middleware"
+       "github.com/deepmap/oapi-codegen/pkg/testutil"
+       echomiddleware "github.com/labstack/echo/v4/middleware"
+       "github.com/stretchr/testify/assert"
+       "github.com/stretchr/testify/mock"
+)
+
+func TestPublishUnpublishService(t *testing.T) {
+       aefId := "aefId"
+       newApiId := "api_id_app-management"
+       serviceRegisterMock := serviceMocks.ServiceRegister{}
+       serviceRegisterMock.On("IsFunctionRegistered", aefId).Return(true)
+       helmManagerMock := helmMocks.HelmManager{}
+       helmManagerMock.On("InstallHelmChart", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil)
+       serviceUnderTest, requestHandler := getEcho(&serviceRegisterMock, &helmManagerMock)
+
+       // Check no services published
+       result := testutil.NewRequest().Get("/aefId/service-apis/"+newApiId).Go(t, requestHandler)
+
+       assert.Equal(t, http.StatusNotFound, result.Code())
+
+       domainName := "domain"
+       var protocol publishapi.Protocol = "HTTP_1_1"
+       description := "Description,namespace,repoName,chartName,releaseName"
+       newServiceDescription := publishapi.ServiceAPIDescription{
+               AefProfiles: &[]publishapi.AefProfile{
+                       {
+                               AefId:      aefId,
+                               DomainName: &domainName,
+                               Protocol:   &protocol,
+                               Versions: []publishapi.Version{
+                                       {
+                                               ApiVersion: "v1",
+                                               Resources: &[]publishapi.Resource{
+                                                       {
+                                                               CommType: "REQUEST_RESPONSE",
+                                                               Operations: &[]publishapi.Operation{
+                                                                       "POST",
+                                                               },
+                                                               ResourceName: "app",
+                                                               Uri:          "app",
+                                                       },
+                                               },
+                                       },
+                               },
+                       },
+               },
+               ApiName:     "app-management",
+               Description: &description,
+       }
+
+       // Publish a service
+       result = testutil.NewRequest().Post("/aefId/service-apis").WithJsonBody(newServiceDescription).Go(t, requestHandler)
+
+       assert.Equal(t, http.StatusCreated, result.Code())
+       var resultService publishapi.ServiceAPIDescription
+       err := result.UnmarshalBodyToObject(&resultService)
+       assert.NoError(t, err, "error unmarshaling response")
+       assert.Equal(t, *resultService.ApiId, newApiId)
+       assert.Equal(t, "http://example.com/"+aefId+"/service-apis/"+*resultService.ApiId, result.Recorder.Header().Get(echo.HeaderLocation))
+       newServiceDescription.ApiId = &newApiId
+       wantedAPILIst := []publishapi.ServiceAPIDescription{newServiceDescription}
+       assert.True(t, serviceUnderTest.AreAPIsRegistered(&wantedAPILIst))
+       assert.True(t, serviceUnderTest.IsAPIRegistered("aefId", "app-management"))
+       serviceRegisterMock.AssertCalled(t, "IsFunctionRegistered", aefId)
+       helmManagerMock.AssertCalled(t, "InstallHelmChart", "namespace", "repoName", "chartName", "releaseName")
+       assert.ElementsMatch(t, wantedAPILIst, *serviceUnderTest.GetAPIs())
+
+       // Check that service is published
+       result = testutil.NewRequest().Get("/aefId/service-apis/"+newApiId).Go(t, requestHandler)
+
+       assert.Equal(t, http.StatusOK, result.Code())
+       err = result.UnmarshalBodyToObject(&resultService)
+       assert.NoError(t, err, "error unmarshaling response")
+       assert.Equal(t, *resultService.ApiId, newApiId)
+
+       // Delete a service
+       helmManagerMock.On("UninstallHelmChart", mock.Anything, mock.Anything).Return(nil)
+       result = testutil.NewRequest().Delete("/aefId/service-apis/"+newApiId).Go(t, requestHandler)
+
+       assert.Equal(t, http.StatusNoContent, result.Code())
+       helmManagerMock.AssertCalled(t, "UninstallHelmChart", "namespace", "chartName")
+       assert.Empty(t, *serviceUnderTest.GetAPIs())
+
+       // Check no services published
+       result = testutil.NewRequest().Get("/aefId/service-apis/"+newApiId).Go(t, requestHandler)
+
+       assert.Equal(t, http.StatusNotFound, result.Code())
+}
+
+func getEcho(serviceRegister providermanagement.ServiceRegister, helmManager helmmanagement.HelmManager) (*PublishService, *echo.Echo) {
+       swagger, err := publishapi.GetSwagger()
+       if err != nil {
+               fmt.Fprintf(os.Stderr, "Error loading swagger spec\n: %s", err)
+               os.Exit(1)
+       }
+
+       swagger.Servers = nil
+
+       ps := NewPublishService(serviceRegister, helmManager)
+
+       e := echo.New()
+       e.Use(echomiddleware.Logger())
+       e.Use(middleware.OapiRequestValidator(swagger))
+
+       publishapi.RegisterHandlers(e, ps)
+       return ps, e
+}
diff --git a/internal/security/security.go b/internal/security/security.go
new file mode 100644 (file)
index 0000000..a5af126
--- /dev/null
@@ -0,0 +1,116 @@
+// -
+//   ========================LICENSE_START=================================
+//   O-RAN-SC
+//   %%
+//   Copyright (C) 2022: Nordix Foundation
+//   %%
+//   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.
+//   ========================LICENSE_END===================================
+//
+
+package security
+
+import (
+       "net/http"
+       "strings"
+
+       "github.com/labstack/echo/v4"
+
+       "oransc.org/nonrtric/sme/internal/common29122"
+       securityapi "oransc.org/nonrtric/sme/internal/securityapi"
+
+       "oransc.org/nonrtric/sme/internal/invokermanagement"
+       "oransc.org/nonrtric/sme/internal/providermanagement"
+       "oransc.org/nonrtric/sme/internal/publishservice"
+)
+
+type Security struct {
+       serviceRegister providermanagement.ServiceRegister
+       apiRegister     publishservice.APIRegister
+       invokerRegister invokermanagement.InvokerRegister
+}
+
+func NewSecurity(serviceRegister providermanagement.ServiceRegister, apiRegister publishservice.APIRegister, invokerRegister invokermanagement.InvokerRegister) *Security {
+       return &Security{
+               serviceRegister: serviceRegister,
+               apiRegister:     apiRegister,
+               invokerRegister: invokerRegister,
+       }
+}
+
+func (s *Security) PostSecuritiesSecurityIdToken(ctx echo.Context, securityId string) error {
+       clientId := ctx.FormValue("client_id")
+       clientSecret := ctx.FormValue("client_secret")
+       // grantType := ctx.FormValue("grant_type")
+       scope := ctx.FormValue("scope")
+
+       if !s.invokerRegister.IsInvokerRegistered(clientId) {
+               return sendCoreError(ctx, http.StatusBadRequest, "Invoker not registered")
+       }
+       if !s.invokerRegister.VerifyInvokerSecret(clientId, clientSecret) {
+               return sendCoreError(ctx, http.StatusBadRequest, "Invoker secret not valid")
+       }
+       if scope != "" {
+               scopeData := strings.Split(strings.Split(scope, "#")[1], ":")
+               if !s.serviceRegister.IsFunctionRegistered(scopeData[0]) {
+                       return sendCoreError(ctx, http.StatusBadRequest, "Function not registered")
+               }
+               if !s.apiRegister.IsAPIRegistered(scopeData[0], scopeData[1]) {
+                       return sendCoreError(ctx, http.StatusBadRequest, "API not published")
+               }
+       }
+
+       accessTokenResp := securityapi.AccessTokenRsp{
+               AccessToken: "asdadfsrt dsr t5",
+               ExpiresIn:   0,
+               Scope:       &scope,
+               TokenType:   "Bearer",
+       }
+
+       err := ctx.JSON(http.StatusCreated, accessTokenResp)
+       if err != nil {
+               // Something really bad happened, tell Echo that our handler failed
+               return err
+       }
+
+       return nil
+}
+
+func (s *Security) DeleteTrustedInvokersApiInvokerId(ctx echo.Context, apiInvokerId string) error {
+       return ctx.NoContent(http.StatusNotImplemented)
+}
+
+func (s *Security) GetTrustedInvokersApiInvokerId(ctx echo.Context, apiInvokerId string, params securityapi.GetTrustedInvokersApiInvokerIdParams) error {
+       return ctx.NoContent(http.StatusNotImplemented)
+}
+
+func (s *Security) PutTrustedInvokersApiInvokerId(ctx echo.Context, apiInvokerId string) error {
+       return ctx.NoContent(http.StatusNotImplemented)
+}
+
+func (s *Security) PostTrustedInvokersApiInvokerIdDelete(ctx echo.Context, apiInvokerId string) error {
+       return ctx.NoContent(http.StatusNotImplemented)
+}
+
+func (s *Security) PostTrustedInvokersApiInvokerIdUpdate(ctx echo.Context, apiInvokerId string) error {
+       return ctx.NoContent(http.StatusNotImplemented)
+}
+
+func sendCoreError(ctx echo.Context, code int, message string) error {
+       pd := common29122.ProblemDetails{
+               Cause:  &message,
+               Status: &code,
+       }
+       err := ctx.JSON(code, pd)
+       return err
+}
diff --git a/internal/security/security_test.go b/internal/security/security_test.go
new file mode 100644 (file)
index 0000000..6eae671
--- /dev/null
@@ -0,0 +1,102 @@
+// -
+//   ========================LICENSE_START=================================
+//   O-RAN-SC
+//   %%
+//   Copyright (C) 2022: Nordix Foundation
+//   %%
+//   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.
+//   ========================LICENSE_END===================================
+//
+
+package security
+
+import (
+       "fmt"
+       "net/http"
+       "net/url"
+       "os"
+       "testing"
+
+       "oransc.org/nonrtric/sme/internal/securityapi"
+
+       "oransc.org/nonrtric/sme/internal/invokermanagement"
+       "oransc.org/nonrtric/sme/internal/providermanagement"
+       "oransc.org/nonrtric/sme/internal/publishservice"
+
+       "github.com/labstack/echo/v4"
+
+       "oransc.org/nonrtric/sme/internal/common29122"
+
+       invokermocks "oransc.org/nonrtric/sme/internal/invokermanagement/mocks"
+       servicemocks "oransc.org/nonrtric/sme/internal/providermanagement/mocks"
+       publishmocks "oransc.org/nonrtric/sme/internal/publishservice/mocks"
+
+       "github.com/deepmap/oapi-codegen/pkg/middleware"
+       "github.com/deepmap/oapi-codegen/pkg/testutil"
+       echomiddleware "github.com/labstack/echo/v4/middleware"
+       "github.com/stretchr/testify/assert"
+       "github.com/stretchr/testify/mock"
+)
+
+func TestPostSecurityIdToken(t *testing.T) {
+       invokerRegisterMock := invokermocks.InvokerRegister{}
+       invokerRegisterMock.On("IsInvokerRegistered", mock.AnythingOfType("string")).Return(true)
+       invokerRegisterMock.On("VerifyInvokerSecret", mock.AnythingOfType("string"), mock.AnythingOfType("string")).Return(true)
+       serviceRegisterMock := servicemocks.ServiceRegister{}
+       serviceRegisterMock.On("IsFunctionRegistered", mock.AnythingOfType("string")).Return(true)
+       apiRegisterMock := publishmocks.APIRegister{}
+       apiRegisterMock.On("IsAPIRegistered", mock.AnythingOfType("string"), mock.AnythingOfType("string")).Return(true)
+
+       requestHandler := getEcho(&serviceRegisterMock, &apiRegisterMock, &invokerRegisterMock)
+
+       data := url.Values{}
+       data.Set("client_id", "id")
+       data.Add("client_secret", "secret")
+       data.Add("grant_type", "client_credentials")
+       data.Add("scope", "scope#aefId:path")
+       encodedData := data.Encode()
+
+       result := testutil.NewRequest().Post("/securities/invokerId/token").WithContentType("application/x-www-form-urlencoded").WithBody([]byte(encodedData)).Go(t, requestHandler)
+
+       assert.Equal(t, http.StatusCreated, result.Code())
+       var resultResponse securityapi.AccessTokenRsp
+       err := result.UnmarshalBodyToObject(&resultResponse)
+       assert.NoError(t, err, "error unmarshaling response")
+       assert.NotEmpty(t, resultResponse.AccessToken)
+       assert.Equal(t, "scope#aefId:path", *resultResponse.Scope)
+       assert.Equal(t, securityapi.AccessTokenRspTokenTypeBearer, resultResponse.TokenType)
+       assert.Equal(t, common29122.DurationSec(0), resultResponse.ExpiresIn)
+       invokerRegisterMock.AssertCalled(t, "IsInvokerRegistered", "id")
+       invokerRegisterMock.AssertCalled(t, "VerifyInvokerSecret", "id", "secret")
+       serviceRegisterMock.AssertCalled(t, "IsFunctionRegistered", "aefId")
+       apiRegisterMock.AssertCalled(t, "IsAPIRegistered", "aefId", "path")
+}
+
+func getEcho(serviceRegister providermanagement.ServiceRegister, apiRegister publishservice.APIRegister, invokerRegister invokermanagement.InvokerRegister) *echo.Echo {
+       swagger, err := securityapi.GetSwagger()
+       if err != nil {
+               fmt.Fprintf(os.Stderr, "Error loading swagger spec\n: %s", err)
+               os.Exit(1)
+       }
+
+       swagger.Servers = nil
+
+       s := NewSecurity(serviceRegister, apiRegister, invokerRegister)
+
+       e := echo.New()
+       e.Use(echomiddleware.Logger())
+       e.Use(middleware.OapiRequestValidator(swagger))
+
+       securityapi.RegisterHandlers(e, s)
+       return e
+}
diff --git a/main.go b/main.go
new file mode 100644 (file)
index 0000000..42ed985
--- /dev/null
+++ b/main.go
@@ -0,0 +1,154 @@
+// -
+//   ========================LICENSE_START=================================
+//   O-RAN-SC
+//   %%
+//   Copyright (C) 2022: Nordix Foundation
+//   %%
+//   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.
+//   ========================LICENSE_END===================================
+//
+
+package main
+
+import (
+       "flag"
+       "fmt"
+       "net/http"
+
+       "github.com/labstack/echo/v4"
+       "oransc.org/nonrtric/sme/internal/discoverserviceapi"
+       "oransc.org/nonrtric/sme/internal/invokermanagementapi"
+       "oransc.org/nonrtric/sme/internal/providermanagementapi"
+       "oransc.org/nonrtric/sme/internal/securityapi"
+
+       "github.com/deepmap/oapi-codegen/pkg/middleware"
+       echomiddleware "github.com/labstack/echo/v4/middleware"
+       log "github.com/sirupsen/logrus"
+       "oransc.org/nonrtric/sme/internal/discoverservice"
+       "oransc.org/nonrtric/sme/internal/helmmanagement"
+       "oransc.org/nonrtric/sme/internal/invokermanagement"
+       "oransc.org/nonrtric/sme/internal/providermanagement"
+       "oransc.org/nonrtric/sme/internal/publishservice"
+       "oransc.org/nonrtric/sme/internal/publishserviceapi"
+       "oransc.org/nonrtric/sme/internal/security"
+)
+
+var url string
+var helmManager helmmanagement.HelmManager
+var repoName string
+
+func main() {
+       var port = flag.Int("port", 8090, "Port for CAPIF Core Function HTTP server")
+       flag.StringVar(&url, "url", "http://chartmuseum:8080", "ChartMuseum url")
+       flag.StringVar(&repoName, "repoName", "local-dev", "Repository name")
+       var logLevelStr = flag.String("loglevel", "Info", "Log level")
+       flag.Parse()
+
+       if loglevel, err := log.ParseLevel(*logLevelStr); err == nil {
+               log.SetLevel(loglevel)
+       }
+
+       // Add repo
+       fmt.Printf("Adding %s to Helm Repo\n", url)
+       helmManager = helmmanagement.NewHelmManager()
+       err := helmManager.AddToRepo(repoName, url)
+       if err != nil {
+               log.Fatal(err.Error())
+       }
+
+       go startWebServer(getEcho(), *port)
+
+       log.Info("Server started and listening on port: ", *port)
+
+       keepServerAlive()
+}
+
+func getEcho() *echo.Echo {
+       // This is how you set up a basic Echo router
+       e := echo.New()
+       // Log all requests
+       e.Use(echomiddleware.Logger())
+
+       var group *echo.Group
+       // Register ProviderManagement
+       providerManagerSwagger, err := providermanagementapi.GetSwagger()
+       if err != nil {
+               log.Fatalf("Error loading ProviderManagement swagger spec\n: %s", err)
+       }
+       providerManagerSwagger.Servers = nil
+       providerManager := providermanagement.NewProviderManager()
+       group = e.Group("/api-provider-management/v1")
+       group.Use(middleware.OapiRequestValidator(providerManagerSwagger))
+       providermanagementapi.RegisterHandlersWithBaseURL(e, providerManager, "/api-provider-management/v1")
+
+       // Register PublishService
+       publishServiceSwagger, err := publishserviceapi.GetSwagger()
+       if err != nil {
+               log.Fatalf("Error loading PublishService swagger spec\n: %s", err)
+       }
+       publishServiceSwagger.Servers = nil
+       publishService := publishservice.NewPublishService(providerManager, helmManager)
+       group = e.Group("/published-apis/v1")
+       group.Use(middleware.OapiRequestValidator(publishServiceSwagger))
+       publishserviceapi.RegisterHandlersWithBaseURL(e, publishService, "/published-apis/v1")
+
+       // Register DiscoverService
+       discoverServiceSwagger, err := discoverserviceapi.GetSwagger()
+       if err != nil {
+               log.Fatalf("Error loading DiscoverService swagger spec\n: %s", err)
+       }
+       discoverServiceSwagger.Servers = nil
+       discoverService := discoverservice.NewDiscoverService(publishService)
+       group = e.Group("/service-apis/v1")
+       group.Use(middleware.OapiRequestValidator(discoverServiceSwagger))
+       discoverserviceapi.RegisterHandlersWithBaseURL(e, discoverService, "/service-apis/v1")
+
+       // Register InvokerManagement
+       invokerManagerSwagger, err := invokermanagementapi.GetSwagger()
+       if err != nil {
+               log.Fatalf("Error loading InvokerManagement swagger spec\n: %s", err)
+       }
+       invokerManagerSwagger.Servers = nil
+       invokerManager := invokermanagement.NewInvokerManager(publishService)
+       group = e.Group("/api-invoker-management/v1")
+       group.Use(middleware.OapiRequestValidator(invokerManagerSwagger))
+       invokermanagementapi.RegisterHandlersWithBaseURL(e, invokerManager, "/api-invoker-management/v1")
+
+       // Register Security
+       securitySwagger, err := publishserviceapi.GetSwagger()
+       if err != nil {
+               log.Fatalf("Error loading Security swagger spec\n: %s", err)
+       }
+       securitySwagger.Servers = nil
+       securityService := security.NewSecurity(providerManager, publishService, invokerManager)
+       group = e.Group("/capif-security/v1")
+       group.Use(middleware.OapiRequestValidator(securitySwagger))
+       securityapi.RegisterHandlersWithBaseURL(e, securityService, "/capif-security/v1")
+
+       e.GET("/", hello)
+
+       return e
+}
+
+func startWebServer(e *echo.Echo, port int) {
+       e.Logger.Fatal(e.Start(fmt.Sprintf("0.0.0.0:%d", port)))
+}
+
+func keepServerAlive() {
+       forever := make(chan int)
+       <-forever
+}
+
+func hello(c echo.Context) error {
+       return c.String(http.StatusOK, "Hello, World!\n")
+}
diff --git a/main_test.go b/main_test.go
new file mode 100644 (file)
index 0000000..383c5aa
--- /dev/null
@@ -0,0 +1,107 @@
+// -
+//   ========================LICENSE_START=================================
+//   O-RAN-SC
+//   %%
+//   Copyright (C) 2022: Nordix Foundation
+//   %%
+//   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.
+//   ========================LICENSE_END===================================
+//
+
+package main
+
+import (
+       "net/http"
+       "testing"
+
+       "github.com/deepmap/oapi-codegen/pkg/testutil"
+       "github.com/labstack/echo/v4"
+       "github.com/stretchr/testify/assert"
+)
+
+var e *echo.Echo
+
+func Test_routing(t *testing.T) {
+       e = getEcho()
+
+       type args struct {
+               url          string
+               returnStatus int
+               method       string
+       }
+       tests := []struct {
+               name string
+               args args
+       }{
+               {
+                       name: "Default path",
+                       args: args{
+                               url:          "/",
+                               returnStatus: http.StatusOK,
+                               method:       "GET",
+                       },
+               },
+               {
+                       name: "Provider path",
+                       args: args{
+                               url:          "/api-provider-management/v1/registrations/provider",
+                               returnStatus: http.StatusNoContent,
+                               method:       "DELETE",
+                       },
+               },
+               {
+                       name: "Publish path",
+                       args: args{
+                               url:          "/published-apis/v1/apfId/service-apis/serviceId",
+                               returnStatus: http.StatusNotFound,
+                               method:       "GET",
+                       },
+               },
+               {
+                       name: "Discover path",
+                       args: args{
+                               url:          "/service-apis/v1/allServiceAPIs?api-invoker-id=api_invoker_id",
+                               returnStatus: http.StatusOK,
+                               method:       "GET",
+                       },
+               },
+               {
+                       name: "Invoker path",
+                       args: args{
+                               url:          "/api-invoker-management/v1/onboardedInvokers/invoker",
+                               returnStatus: http.StatusNoContent,
+                               method:       "DELETE",
+                       },
+               },
+               {
+                       name: "Security path",
+                       args: args{
+                               url:          "/capif-security/v1/trustedInvokers/apiInvokerId",
+                               returnStatus: http.StatusNotImplemented,
+                               method:       "GET",
+                       },
+               },
+       }
+       for _, tt := range tests {
+               t.Run(tt.name, func(t *testing.T) {
+                       var result *testutil.CompletedRequest
+                       if tt.args.method == "GET" {
+                               result = testutil.NewRequest().Get(tt.args.url).Go(t, e)
+                       } else if tt.args.method == "DELETE" {
+                               result = testutil.NewRequest().Delete(tt.args.url).Go(t, e)
+                       }
+
+                       assert.Equal(t, tt.args.returnStatus, result.Code(), tt.name)
+               })
+       }
+}