diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000000000000000000000000000000000000..8fff60fd57f7fba983e1473465cccbbf124caa8c --- /dev/null +++ b/.dockerignore @@ -0,0 +1,12 @@ +.git +.gitlab +build +documentation +mocks +test +.cobra.yaml +.dockeringore +.gitlab-ci.yaml +ARCHITECTURE.md +CONTRIBUTING.md +README.md diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000000000000000000000000000000000..1263e404822d3f5060eb5492b0db34bcc91b5085 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +root = true + +[*] +indent_style = space +indent_size = 4 +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true +end_of_line = lf + +[{*.yaml, *.yml}] +indent_size = 2 diff --git a/.gitignore b/.gitignore index 78c6e10062c15b5eb23543e4c43b585851060baa..016de7ce1ea2f9c56a6b051ff1f8b79900bfb67a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ - +.vscode/ +.vscode/launch.json .DS_Store documentation/design-documentation/ documentation/design/*.pdf @@ -14,4 +15,16 @@ documentation/design/*.pdf .idea/workspace.xml restconf/bin/bin test/.terraform.local/ -configs/gosdn.toml \ No newline at end of file +configs/gosdn.toml +api/api_test.toml +debug.test + +# test files +report.xml +nucleus/util/proto/*_test + +# Binary +gosdn + +# persistent data +**/stores/** diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a720721820c41bdd318d49dc93302cf295527f0f..8929b266e9bf9595876b07316bcbade972de6e72 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,24 +1,24 @@ variables: - SECURE_ANALYZERS_PREFIX: registry.gitlab.com/gitlab-org/security-products/analyzers - DOCKER_IMAGE_SHA: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA + GOSDN_IMAGE: "${CI_REGISTRY_IMAGE}:${CI_COMMIT_SHA}" + GOSDN_TESTING_IMAGE: "${CI_REGISTRY_IMAGE}:testing_${CI_COMMIT_SHA}" + CEOS_IMAGE: "$CI_REGISTRY_IMAGE/ceos:latest" + GOLANG_VERSION: "1.17" stages: - - .pre - - test - build + - test + - analyze - apply - integration-test - - deploy + - build-release - .post -default: - before_script: - - git config --global url."https://$GO_MODULES_USER:$GO_MODULES_ACCESS_TOKEN@code.fbi.h-da.de".insteadOf "https://code.fbi.h-da.de" - include: - - local: '/build/ci/.code-quality-ci.yml' - - local: '/build/ci/.security-and-compliance-ci.yml' - - local: '/build/ci/.build-container.yml' - - local: '/build/ci/.test.yml' - - local: '/build/ci/.terraform-ci.yml' - - local: '/build/ci/.deploy-k8s.yml' \ No newline at end of file + - local: '/.gitlab/ci/.build-container.yml' + - local: '/.gitlab/ci/.code-quality-ci.yml' + - local: '/.gitlab/ci/.security-and-compliance-ci.yml' + - local: '/.gitlab/ci/.test.yml' + - local: '/.gitlab/ci/.containerlab-ci.yml' + - local: '/.gitlab/ci/.integration-test.yml' + - local: '/.gitlab/ci/.uml-autogen-ci.yml' + - local: '/.gitlab/ci/.build-release.yml' diff --git a/.gitlab/ci/.build-container.yml b/.gitlab/ci/.build-container.yml new file mode 100644 index 0000000000000000000000000000000000000000..d948433abc50ff82f4abf39ebef2953c0aa4543a --- /dev/null +++ b/.gitlab/ci/.build-container.yml @@ -0,0 +1,59 @@ +.build: &build + stage: build + image: + name: gcr.io/kaniko-project/executor:debug + entrypoint: [ "" ] + variables: + TAG: $CI_COMMIT_BRANCH + before_script: + # replace all slashes in the tag with hyphen, because slashes are not allowed in tags + - TAG=${TAG//\//-} + - mkdir -p /kaniko/.docker + - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"},\"$CI_DEPENDENCY_PROXY_SERVER\":{\"username\":\"$CI_DEPENDENCY_PROXY_USER\",\"password\":\"$CI_DEPENDENCY_PROXY_TOKEN\"}}}" > /kaniko/.docker/config.json + needs: [] + +build-testing-image: + rules: + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + variables: + TAG: latest + - if: $CI_COMMIT_BRANCH == "develop" + variables: + TAG: $CI_COMMIT_BRANCH + BUILDARGS: -race + - when: always + script: + - /kaniko/executor + --cache=true + --context "$CI_PROJECT_DIR" + --dockerfile "Dockerfile" + --build-arg "GOLANG_VERSION=$GOLANG_VERSION" + --build-arg "BUILDARGS=$BUILDARGS" + --build-arg "GITLAB_PROXY=${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/" + --destination "$GOSDN_TESTING_IMAGE" + --target "installer" + <<: *build + +build-image: + rules: + - if: '$CI_PIPELINE_SOURCE != "merge_request_event"' + when: never + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + variables: + TAG: $CI_DEFAULT_BRANCH + - if: $CI_COMMIT_BRANCH == "develop" + variables: + TAG: develop + BUILDARGS: -race + - when: always + script: + - /kaniko/executor + --cache=true + --context "$CI_PROJECT_DIR" + --dockerfile "Dockerfile" + --build-arg "GOLANG_VERSION=$GOLANG_VERSION" + --build-arg "BUILDARGS=$BUILDARGS" + --build-arg "GITLAB_PROXY=${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/" + --destination "$GOSDN_IMAGE" + --destination "$CI_REGISTRY_IMAGE:$TAG" + <<: *build diff --git a/.gitlab/ci/.build-release.yml b/.gitlab/ci/.build-release.yml new file mode 100644 index 0000000000000000000000000000000000000000..e671eb527b66ead794eba0bd3f2fa22f7c0fdda2 --- /dev/null +++ b/.gitlab/ci/.build-release.yml @@ -0,0 +1,86 @@ +.build-release-docker: &build-release-docker + stage: build-release + image: + name: gcr.io/kaniko-project/executor:debug + entrypoint: [ "" ] + rules: + # TODO: Implement later when we need it + #- if: $CI_COMMIT_TAG =~ .+ && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + # variables: + # TAG: $CI_COMMIT_TAG + # when: on_success + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + variables: + TAG: $CI_DEFAULT_BRANCH + when: on_success + - when: never + before_script: + # replace all slashes in the tag with hyphen, because slashes are not allowed in tags + - TAG=${TAG//\//-} + - mkdir -p /kaniko/.docker + - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"},\"$CI_DEPENDENCY_PROXY_SERVER\":{\"username\":\"$CI_DEPENDENCY_PROXY_USER\",\"password\":\"$CI_DEPENDENCY_PROXY_TOKEN\"}}}" > /kaniko/.docker/config.json + +build-release-image: + script: + - /kaniko/executor + --cache=true + --context "$CI_PROJECT_DIR" + --dockerfile "Dockerfile" + --build-arg "GOLANG_VERSION=$GOLANG_VERSION" + --build-arg "BUILDARGS=$BUILDARGS" + --build-arg "GITLAB_PROXY=${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/" + --destination "$GOSDN_IMAGE" + --destination "$CI_REGISTRY_IMAGE:$TAG" + - /kaniko/executor + --cache=true + --context "$CI_PROJECT_DIR" + --dockerfile "Dockerfile" + --build-arg "GOLANG_VERSION=$GOLANG_VERSION" + --build-arg "BUILDARGS=$BUILDARGS" + --build-arg "GITLAB_PROXY=${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/" + --destination "$GOSDN_IMAGE" + --destination "$CI_REGISTRY_IMAGE:latest" + <<: *build-release-docker + + +.build-release-binary: &build-release-binary + stage: build-release + image: + name: ${GITLAB_PROXY}golang:$GOLANG_VERSION + rules: + # TODO: Implement later when we need it + #- if: $CI_COMMIT_TAG =~ .+ && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + # variables: + # TAG: $CI_COMMIT_TAG + # when: on_success + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + variables: + TAG: $CI_DEFAULT_BRANCH + when: on_success + - if: $CI_COMMIT_BRANCH == "develop" + variables: + TAG: $CI_COMMIT_BRANCH + when: on_success + - when: never + +build-release-linux: + script: + - GOOS=linux go build ./cmd/gosdn + - mv gosdn gosdn-$TAG + - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file gosdn-$TAG "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/gosdn/$TAG/gosdn-$TAG-linux"' + artifacts: + paths: + - gosdn-$TAG + expire_in: 4 weeks + <<: *build-release-binary + +build-release-freebsd: + script: + - GOOS=freebsd go build ./cmd/gosdn + - mv gosdn gosdn-$TAG + - - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file gosdn-$TAG "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/gosdn/$TAG/gosdn-$TAG-freebsd"' + artifacts: + paths: + - gosdn-$TAG + expire_in: 4 weeks + <<: *build-release-binary \ No newline at end of file diff --git a/.gitlab/ci/.code-quality-ci.yml b/.gitlab/ci/.code-quality-ci.yml new file mode 100644 index 0000000000000000000000000000000000000000..9a66d4a43c51a22d54fccdfa05ef6617e1a7d889 --- /dev/null +++ b/.gitlab/ci/.code-quality-ci.yml @@ -0,0 +1,12 @@ +code-quality: + image: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/golangci/golangci-lint:v1.42-alpine + stage: analyze + script: + # writes golangci-lint output to gl-code-quality-report.json + - golangci-lint run --config .gitlab/ci/.golangci-config/.golangci.yml --out-format code-climate | tee gl-code-quality-report.json + artifacts: + reports: + codequality: gl-code-quality-report.json + paths: + - gl-code-quality-report.json + needs: [] diff --git a/.gitlab/ci/.containerlab-ci.yml b/.gitlab/ci/.containerlab-ci.yml new file mode 100644 index 0000000000000000000000000000000000000000..f3a06f8ad8ef783f36b176cab610549781be6cac --- /dev/null +++ b/.gitlab/ci/.containerlab-ci.yml @@ -0,0 +1,127 @@ +variables: + CLAB_DIR: "/mnt" + CLAB_NAME: "clab${CI_PIPELINE_IID}" + +# Templates for Job Types +.containerlab_deploy: &containerlab_deploy + stage: apply + rules: + - if: '$CI_PIPELINE_SOURCE != "merge_request_event"' + when: never + - when: on_success + tags: + - shell + before_script: + - cd ${CLAB_DIR} + - export PATH="${PATH}:${CI_PROJECT_DIR}/.gitlab/ci/scripts" + - echo "$CI_REGISTRY_PASSWORD" | docker login -u $CI_REGISTRY_USER --password-stdin $CI_REGISTRY + - echo ${GOSDN_IMAGE} + - docker pull ${GOSDN_IMAGE} + - docker pull ${CEOS_IMAGE} + +.containerlab_template: &containerlab_template + image: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/alpine:latest + stage: build + rules: + - if: '$CI_PIPELINE_SOURCE != "merge_request_event"' + when: never + - when: on_success + before_script: + - export PATH="${PATH}:${CI_PROJECT_DIR}/.gitlab/ci/scripts" + - firstOctet=$(generate_octet.sh $CI_COMMIT_SHA) + - secondOctet=$(generate_octet.sh $CI_PIPELINE_ID) + - export CLAB_MGMT_SUBNET="172.$firstOctet.$secondOctet.0/24" + script: + - | + sed -e "s|@@CEOS_CONTAINER_IMAGE@@|${CEOS_IMAGE}|g" \ + -e "s|@@GOSDN_CONTAINER_IMAGE@@|${GOSDN_IMAGE}|g" \ + -e "s|@@CLAB_NAME@@|${CLAB_NAME}|g" \ + -e "s|@@CLAB_MGMT_SUBNET@@|${CLAB_MGMT_SUBNET}|g" \ + ${CLAB_TEMPLATE} > ${CLAB_NAME}.clab.yml + - cat ${CLAB_NAME}.clab.yml + artifacts: + name: ${CLAB_NAME} + paths: + - ${CLAB_NAME}.clab.yml + +# JOBS +containerlab:template:integration: + extends: .containerlab_template + variables: + CLAB_TEMPLATE: "${CI_PROJECT_DIR}/test/containerlab/int01.clab.tmpl.yml" + + +containerlab:deploy:integration: + extends: .containerlab_deploy + needs: ["containerlab:template:integration", "build-image"] + script: + - sudo containerlab deploy --topo ${CI_PROJECT_DIR}/${CLAB_NAME}.clab.yml --reconfigure + - | + echo -e "\ + GOSDN_HTTP_PORT=$(docker_host_port 8080 clab-${CLAB_NAME}-gosdn)\n\ + GOSDN_GRPC_PORT=$(docker_host_port 55055 clab-${CLAB_NAME}-gosdn)\n\ + CEOS1_PORT=$(docker_host_port 6030 clab-${CLAB_NAME}-ceos1)" \ + > ${CI_PROJECT_DIR}/build.env + - cat ${CI_PROJECT_DIR}/build.env + artifacts: + reports: + dotenv: ${CI_PROJECT_DIR}/build.env + + +containerlab:destroy: + rules: + - if: '$CI_PIPELINE_SOURCE != "merge_request_event"' + when: never + - when: always + stage: .post + tags: + - shell + needs: ["containerlab:deploy:integration", "integration-test:nucleus", "integration-test:api", "containerlab:template:integration"] + before_script: + - cd ${CLAB_DIR} + script: + - sudo containerlab destroy --topo ${CI_PROJECT_DIR}/${CLAB_NAME}.clab.yml + - docker volume rm -f ${CLAB_NAME}-volume + - docker image rm -f ${GOSDN_IMAGE} + allow_failure: true + + +#containerlab:template:develop: +# extends: .containerlab_template +# variables: +# CLAB_NAME: "dev" +# CLAB_TEMPLATE: "${CI_PROJECT_DIR}/test/containerlab/dev.clab.tmpl.yml" +# GOSDN_CONTAINER_IMAGE: "$CI_REGISTRY_IMAGE:develop" +# rules: +# - if: $CI_COMMIT_BRANCH == 'develop' && $CI_NIGHTLY == null +# +# +#containerlab:deploy:develop: +# extends: +# - .containerlab_deploy +# needs: ["containerlab:template:develop", "build-image"] +# variables: +# CLAB_NAME: "dev" +# GOSDN_CONTAINER_IMAGE: "$CI_REGISTRY_IMAGE:develop" +# script: +# - sudo containerlab deploy --topo ${CI_PROJECT_DIR}/${CLAB_NAME}.clab.yml --reconfigure +# rules: +# - if: $CI_COMMIT_BRANCH == 'develop' && $CI_NIGHTLY == null + + +containerlab:clean: + stage: .post + tags: + - shell + before_script: + - cd ${CLAB_DIR} + script: + - docker kill $(docker ps -q) || true + - docker rm $(docker ps -a -q) || true + - docker rmi $(docker images | grep 'registry.code.fbi.h-da.de/danet/gosdn ' | awk '{print $3}') || true + - sudo rm -rf ${CLAB_DIR}/clab-* || true + - sudo sed -i 's|.*clab.*||g' /etc/hosts + allow_failure: true + rules: + - if: $CI_SCHEDULE_CLEAN + when: always diff --git a/build/ci/.deploy-k8s.yml b/.gitlab/ci/.deploy-k8s.yml similarity index 61% rename from build/ci/.deploy-k8s.yml rename to .gitlab/ci/.deploy-k8s.yml index 7046b8e9242868e62a8503ad7cc81599603780b4..e2d8e52baae3834784bfd8cbe1a36f38d699b3bd 100644 --- a/build/ci/.deploy-k8s.yml +++ b/.gitlab/ci/.deploy-k8s.yml @@ -1,10 +1,9 @@ build:k8s-bot: stage: build - image: golang:1.16 + image: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/golang:$GOLANG_VERSION rules: - if: $CI_COMMIT_BRANCH == "develop" - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - - if: $CI_PIPELINE_SOURCE == "merge_request_event" script: - cd build/cd - go build -o k8s-bot @@ -14,7 +13,9 @@ build:k8s-bot: - build/cd/k8s-bot .deploy: &deploy - image: bitnami/kubectl:latest + image: + name: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/bitnami/kubectl:latest + entrypoint: [""] before_script: - echo "override global before script" variables: @@ -22,21 +23,11 @@ build:k8s-bot: script: - ./build/cd/k8s-bot -deploy:integration-test: - <<: *deploy - stage: apply - needs: - - job: "build:merge-request" - - job: "build:k8s-bot" - artifacts: true - rules: - - if: $CI_PIPELINE_SOURCE == "merge_request_event" - deploy:develop: <<: *deploy stage: deploy needs: - - job: "build:develop" + - job: "build-docker" - job: "build:k8s-bot" artifacts: true rules: @@ -46,7 +37,7 @@ deploy:latest: <<: *deploy stage: deploy needs: - - job: "build:latest" + - job: "build-docker" - job: "build:k8s-bot" artifacts: true rules: @@ -56,7 +47,7 @@ deploy:nightly:mainline: <<: *deploy stage: deploy needs: - - job: "build:latest" + - job: "build-docker" - job: "build:k8s-bot" artifacts: true rules: @@ -66,23 +57,8 @@ deploy:nightly:develop: <<: *deploy stage: deploy needs: - - job: "build:latest" + - job: "build-docker" - job: "build:k8s-bot" artifacts: true rules: - if: $CI_COMMIT_BRANCH == "develop" && $CI_NIGHTLY == "mainline" - -destroy:k8s: - image: bitnami/kubectl:latest - rules: - - if: $CI_PIPELINE_SOURCE == "merge_request_event" - when: always - before_script: - - echo "override global before script" - stage: .post - variables: - K8S_OP: "delete" - script: - - ./build/cd/k8s-bot - dependencies: - - build:k8s-bot \ No newline at end of file diff --git a/build/ci/.golangci-config/.golangci.yml b/.gitlab/ci/.golangci-config/.golangci.yml similarity index 77% rename from build/ci/.golangci-config/.golangci.yml rename to .gitlab/ci/.golangci-config/.golangci.yml index 1ca12a130fcef6a4ff882340c5c1f981c0804521..e9ea64defdbb908d5d1892ff7f8351aaa6cc7a6a 100644 --- a/build/ci/.golangci-config/.golangci.yml +++ b/.gitlab/ci/.golangci-config/.golangci.yml @@ -1,5 +1,5 @@ run: - timeout: 5m + timeout: 10m issues-exit-code: 1 # directories to be ignored by linters skip-dirs: @@ -7,7 +7,7 @@ run: - test skip-dirs-default: true skip-files: - - nucleus/http.go + - http.go # output settings -> code-climate for GitLab output: format: code-climate @@ -26,8 +26,15 @@ linters: disable-all: true enable: - gofmt - - golint + - goimports - gocyclo - govet + - unused + - staticcheck + - typecheck + - revive + - whitespace issues: exclude-use-default: false + max-issues-per-linter: 0 + max-same-issues: 0 diff --git a/build/ci/.golangci-config/.runlint.sh b/.gitlab/ci/.golangci-config/.runlint.sh similarity index 100% rename from build/ci/.golangci-config/.runlint.sh rename to .gitlab/ci/.golangci-config/.runlint.sh diff --git a/.gitlab/ci/.integration-test.yml b/.gitlab/ci/.integration-test.yml new file mode 100644 index 0000000000000000000000000000000000000000..dc80d9815835f0c4231c5248234be38958da64dd --- /dev/null +++ b/.gitlab/ci/.integration-test.yml @@ -0,0 +1,36 @@ +.integration-test: &integration-test + image: $GOSDN_TESTING_IMAGE + stage: integration-test + rules: + - if: '$CI_PIPELINE_SOURCE != "merge_request_event"' + when: never + - when: on_success + needs: + - job: "containerlab:deploy:integration" + tags: + - integration-test-docker + variables: + GOSDN_LOG: "nolog" + GOSDN_TEST_API_ENDPOINT: "141.100.70.178:${GOSDN_GRPC_PORT}" + CEOS_TEST_ENDPOINT: "141.100.70.178:${CEOS1_PORT}" + GOSDN_TEST_USER: "admin" + GOSDN_TEST_PASSWORD: "admin" + + +integration-test:nucleus: + <<: *integration-test + script: + - ${CI_PROJECT_DIR}/.gitlab/ci/scripts/wait-for-it.sh ${CEOS_TEST_ENDPOINT} -s -t 180 -- echo "CEOS is up" + - cd ./test/integration + - go test -race -v -run TestGnmi_SetIntegration + - go test -race -v -run TestGnmi_GetIntegration + - go test -race -v -run TestGnmi_SubscribeIntegration + - go test -race -v -run TestGnmi_CapabilitiesIntegration + +integration-test:api: + <<: *integration-test + variables: + K8S_OP: "getenv" + script: + - cd ./api + - go test -race -v -run TestApiIntegration diff --git a/.gitlab/ci/.security-and-compliance-ci.yml b/.gitlab/ci/.security-and-compliance-ci.yml new file mode 100644 index 0000000000000000000000000000000000000000..a42c6695e77f10cfb7440e317bfbd0b73a629da9 --- /dev/null +++ b/.gitlab/ci/.security-and-compliance-ci.yml @@ -0,0 +1,48 @@ +.rules: &rules + stage: analyze + rules: + - if: '$CI_PIPELINE_SOURCE != "merge_request_event"' + when: never + - when: always + needs: [] + +sast: + variables: + SAST_ANALYZER_IMAGE_TAG: '2' + SAST_EXCLUDED_PATHS: spec, test, tests, tmp + SEARCH_MAX_DEPTH: '4' + +include: + - template: Security/SAST.gitlab-ci.yml + - template: Dependency-Scanning.gitlab-ci.yml + - template: Security/License-Scanning.gitlab-ci.yml +# - template: Security/Secret-Detection.gitlab-ci.yml + - template: Security/Container-Scanning.gitlab-ci.yml + +gemnasium-dependency_scanning: + <<: *rules + +gosec-sast: + <<: *rules + +license_scanning: + <<: *rules + +semgrep-sast: + <<: *rules + +#secret_detection: +# <<: *rules + +container_scanning: + stage: analyze + rules: + - if: '$CI_PIPELINE_SOURCE != "merge_request_event"' + when: never + - when: always + variables: + DOCKER_IMAGE: "${GOSDN_IMAGE}" + DOCKER_USER: "${CI_REGISTRY_USER}" + DOCKER_PASSWORD: "${CI_REGISTRY_PASSWORD}" + needs: + - build-image diff --git a/.gitlab/ci/.test.yml b/.gitlab/ci/.test.yml new file mode 100644 index 0000000000000000000000000000000000000000..762da835770a5f8e3666f8287a18a1d83b6db509 --- /dev/null +++ b/.gitlab/ci/.test.yml @@ -0,0 +1,35 @@ +.test: &test + image: $GOSDN_TESTING_IMAGE + stage: test + rules: + - when: on_success + variables: + GOSDN_LOG: "nolog" + GOSDN_CHANGE_TIMEOUT: "100ms" + before_script: + - go get gotest.tools/gotestsum + artifacts: + when: always + reports: + junit: report.xml + needs: + - build-testing-image + +unit-test: + script: + - gotestsum --junitfile report.xml --format testname -- -short -race $(go list ./... | grep -v /forks/ | grep -v /mocks ) -v -coverprofile=coverage.out + after_script: + - go tool cover -func=coverage.out + <<: *test + +controller-test: + script: + - gotestsum --junitfile report.xml --format testname -- -race -v -run TestRun + <<: *test + +test-build: + artifacts: + when: never + script: + - GOOS=linux go build $BUILDARGS ./cmd/gosdn + <<: *test diff --git a/.gitlab/ci/.uml-autogen-ci.yml b/.gitlab/ci/.uml-autogen-ci.yml new file mode 100644 index 0000000000000000000000000000000000000000..adaf8c99dc09056b5183d0177e7c3e7dfaf6a5b3 --- /dev/null +++ b/.gitlab/ci/.uml-autogen-ci.yml @@ -0,0 +1,31 @@ +goplantuml: + image: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/golang:$GOLANG_VERSION + stage: .post + only: + - develop + when: manual + variables: + FILENAME: "home.md" + WIKI_URL: "${CI_SERVER_PROTOCOL}://project_${CI_PROJECT_ID}_bot3:${GOPLANTUML_TOKEN}@${CI_SERVER_HOST}:${CI_SERVER_PORT}/${CI_PROJECT_PATH}.wiki.git" + + script: + # install goplantuml + - go get github.com/jfeliu007/goplantuml/cmd/goplantuml + # remove old wiki folder + - rm -rf "/tmp/${CI_PROJECT_NAME}.wiki" + # clone and move to wiki folder + - cd /tmp + - git clone "${WIKI_URL}" + - cd "${CI_PROJECT_NAME}.wiki" + + - echo '```plantuml' > "$FILENAME" + # run goplantuml + - goplantuml "${CI_PROJECT_DIR}/nucleus/" >> "$FILENAME" + - echo '```' >> "$FILENAME" + + # git commit + - git config user.name "$GITLAB_USER_NAME" + - git config user.email "$GITLAB_USER_EMAIL" + - git add "$FILENAME" + - git commit -m "Auto-updated UML diagram via goplantuml CI job" + - git push origin "HEAD:master" diff --git a/.gitlab/ci/scripts/docker_host_port b/.gitlab/ci/scripts/docker_host_port new file mode 100644 index 0000000000000000000000000000000000000000..42ac183f4263c80e1120884b524233952b05e229 --- /dev/null +++ b/.gitlab/ci/scripts/docker_host_port @@ -0,0 +1,3 @@ +#!/bin/sh +TEMPLATE="{{ (index (index .NetworkSettings.Ports \"${1}/tcp\") 0).HostPort }}" +docker inspect -f "${TEMPLATE}" ${2} diff --git a/.gitlab/ci/scripts/generate_octet.sh b/.gitlab/ci/scripts/generate_octet.sh new file mode 100755 index 0000000000000000000000000000000000000000..9d5dce7312a7ab516bd01d208ac961d5e23fe955 --- /dev/null +++ b/.gitlab/ci/scripts/generate_octet.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +input=$1 +#trailing_backspace=$2 + +hashed_value=$(echo $input | sha256sum | awk '{print $1}' ) + +decimal_value=$((16#$hashed_value)) +decimal_value=${decimal_value/-/} + +octet=$(((decimal_value % 255))) + +echo -n $octet diff --git a/.gitlab/ci/scripts/wait-for-it.sh b/.gitlab/ci/scripts/wait-for-it.sh new file mode 100755 index 0000000000000000000000000000000000000000..d990e0d364f576ee83cd699707076ca49ad36a4d --- /dev/null +++ b/.gitlab/ci/scripts/wait-for-it.sh @@ -0,0 +1,182 @@ +#!/usr/bin/env bash +# Use this script to test if a given TCP host/port are available + +WAITFORIT_cmdname=${0##*/} + +echoerr() { if [[ $WAITFORIT_QUIET -ne 1 ]]; then echo "$@" 1>&2; fi } + +usage() +{ + cat << USAGE >&2 +Usage: + $WAITFORIT_cmdname host:port [-s] [-t timeout] [-- command args] + -h HOST | --host=HOST Host or IP under test + -p PORT | --port=PORT TCP port under test + Alternatively, you specify the host and port as host:port + -s | --strict Only execute subcommand if the test succeeds + -q | --quiet Don't output any status messages + -t TIMEOUT | --timeout=TIMEOUT + Timeout in seconds, zero for no timeout + -- COMMAND ARGS Execute command with args after the test finishes +USAGE + exit 1 +} + +wait_for() +{ + if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then + echoerr "$WAITFORIT_cmdname: waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT" + else + echoerr "$WAITFORIT_cmdname: waiting for $WAITFORIT_HOST:$WAITFORIT_PORT without a timeout" + fi + WAITFORIT_start_ts=$(date +%s) + while : + do + if [[ $WAITFORIT_ISBUSY -eq 1 ]]; then + nc -z $WAITFORIT_HOST $WAITFORIT_PORT + WAITFORIT_result=$? + else + (echo -n > /dev/tcp/$WAITFORIT_HOST/$WAITFORIT_PORT) >/dev/null 2>&1 + WAITFORIT_result=$? + fi + if [[ $WAITFORIT_result -eq 0 ]]; then + WAITFORIT_end_ts=$(date +%s) + echoerr "$WAITFORIT_cmdname: $WAITFORIT_HOST:$WAITFORIT_PORT is available after $((WAITFORIT_end_ts - WAITFORIT_start_ts)) seconds" + break + fi + sleep 1 + done + return $WAITFORIT_result +} + +wait_for_wrapper() +{ + # In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692 + if [[ $WAITFORIT_QUIET -eq 1 ]]; then + timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --quiet --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT & + else + timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT & + fi + WAITFORIT_PID=$! + trap "kill -INT -$WAITFORIT_PID" INT + wait $WAITFORIT_PID + WAITFORIT_RESULT=$? + if [[ $WAITFORIT_RESULT -ne 0 ]]; then + echoerr "$WAITFORIT_cmdname: timeout occurred after waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT" + fi + return $WAITFORIT_RESULT +} + +# process arguments +while [[ $# -gt 0 ]] +do + case "$1" in + *:* ) + WAITFORIT_hostport=(${1//:/ }) + WAITFORIT_HOST=${WAITFORIT_hostport[0]} + WAITFORIT_PORT=${WAITFORIT_hostport[1]} + shift 1 + ;; + --child) + WAITFORIT_CHILD=1 + shift 1 + ;; + -q | --quiet) + WAITFORIT_QUIET=1 + shift 1 + ;; + -s | --strict) + WAITFORIT_STRICT=1 + shift 1 + ;; + -h) + WAITFORIT_HOST="$2" + if [[ $WAITFORIT_HOST == "" ]]; then break; fi + shift 2 + ;; + --host=*) + WAITFORIT_HOST="${1#*=}" + shift 1 + ;; + -p) + WAITFORIT_PORT="$2" + if [[ $WAITFORIT_PORT == "" ]]; then break; fi + shift 2 + ;; + --port=*) + WAITFORIT_PORT="${1#*=}" + shift 1 + ;; + -t) + WAITFORIT_TIMEOUT="$2" + if [[ $WAITFORIT_TIMEOUT == "" ]]; then break; fi + shift 2 + ;; + --timeout=*) + WAITFORIT_TIMEOUT="${1#*=}" + shift 1 + ;; + --) + shift + WAITFORIT_CLI=("$@") + break + ;; + --help) + usage + ;; + *) + echoerr "Unknown argument: $1" + usage + ;; + esac +done + +if [[ "$WAITFORIT_HOST" == "" || "$WAITFORIT_PORT" == "" ]]; then + echoerr "Error: you need to provide a host and port to test." + usage +fi + +WAITFORIT_TIMEOUT=${WAITFORIT_TIMEOUT:-15} +WAITFORIT_STRICT=${WAITFORIT_STRICT:-0} +WAITFORIT_CHILD=${WAITFORIT_CHILD:-0} +WAITFORIT_QUIET=${WAITFORIT_QUIET:-0} + +# Check to see if timeout is from busybox? +WAITFORIT_TIMEOUT_PATH=$(type -p timeout) +WAITFORIT_TIMEOUT_PATH=$(realpath $WAITFORIT_TIMEOUT_PATH 2>/dev/null || readlink -f $WAITFORIT_TIMEOUT_PATH) + +WAITFORIT_BUSYTIMEFLAG="" +if [[ $WAITFORIT_TIMEOUT_PATH =~ "busybox" ]]; then + WAITFORIT_ISBUSY=1 + # Check if busybox timeout uses -t flag + # (recent Alpine versions don't support -t anymore) + if timeout &>/dev/stdout | grep -q -e '-t '; then + WAITFORIT_BUSYTIMEFLAG="-t" + fi +else + WAITFORIT_ISBUSY=0 +fi + +if [[ $WAITFORIT_CHILD -gt 0 ]]; then + wait_for + WAITFORIT_RESULT=$? + exit $WAITFORIT_RESULT +else + if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then + wait_for_wrapper + WAITFORIT_RESULT=$? + else + wait_for + WAITFORIT_RESULT=$? + fi +fi + +if [[ $WAITFORIT_CLI != "" ]]; then + if [[ $WAITFORIT_RESULT -ne 0 && $WAITFORIT_STRICT -eq 1 ]]; then + echoerr "$WAITFORIT_cmdname: strict mode, refusing to execute subprocess" + exit $WAITFORIT_RESULT + fi + exec "${WAITFORIT_CLI[@]}" +else + exit $WAITFORIT_RESULT +fi diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000000000000000000000000000000000..54d4afcda97795f447fa18470f930aed67aa82b3 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "documentation/manual"] + path = documentation/manual + url = https://git.overleaf.com/620142e0fbf7476b92f7240a diff --git a/Dockerfile b/Dockerfile index b8a7b9cab2bfcbec7da50a41abda0e0e445167cf..0e9227f3eb32885934ca7c235d988624df538d27 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,18 +1,24 @@ -FROM golang:1.16-buster AS builder -ARG GITLAB_USER -ARG GITLAB_TOKEN +ARG GOLANG_VERSION=1.17 ARG BUILDARGS +ARG $GITLAB_PROXY + +FROM ${GITLAB_PROXY}golang:$GOLANG_VERSION-buster AS installer + WORKDIR /src/gosdn -COPY . . -RUN apt-get update && apt-get install -y git -RUN git config --global url."https://$GITLAB_USER:$GITLAB_TOKEN@code.fbi.h-da.de".insteadOf "https://code.fbi.h-da.de" +COPY go.* ./ +RUN go mod download + +FROM installer as builder + +COPY . ./ + RUN GOOS=linux go build $BUILDARGS ./cmd/gosdn -FROM debian:latest +FROM ${GITLAB_PROXY}debian:bullseye EXPOSE 8080 EXPOSE 55055 COPY --from=builder /src/gosdn/gosdn . -COPY --from=builder /src/gosdn/configs ./configs +COPY ./configs ./configs ENTRYPOINT [ "./gosdn" ] CMD [""] diff --git a/Dockerfile.debug b/Dockerfile.debug new file mode 100644 index 0000000000000000000000000000000000000000..a2460463b036732da3b6d6f17539377a8f054f40 --- /dev/null +++ b/Dockerfile.debug @@ -0,0 +1,28 @@ +# syntax = docker/dockerfile:1.2 + +FROM golang:1.16-alpine AS builder +ARG GITLAB_USER +ARG GITLAB_TOKEN +ARG BUILDARGS +WORKDIR /src/gosdn +RUN apk add --no-cache git make build-base +RUN git config --global url."https://$GITLAB_USER:$GITLAB_TOKEN@code.fbi.h-da.de".insteadOf "https://code.fbi.h-da.de" +COPY go.mod . +COPY go.sum . +RUN go mod download +COPY . . +RUN --mount=type=cache,target=/root/.cache/go-build \ +GOOS=linux go build -o gosdn ./cmd/gosdn + +# Get Delve from a GOPATH not from a Go Modules project +WORKDIR /go/src/ +RUN go get github.com/go-delve/delve/cmd/dlv + +FROM alpine +EXPOSE 8080 +EXPOSE 55055 +EXPOSE 40000 +COPY --from=builder /src/gosdn / +COPY --from=builder /go/bin/dlv / + +CMD ["/dlv", "--listen=:40000", "--headless=true", "--api-version=2", "exec", "/gosdn"] \ No newline at end of file diff --git a/Programming.md b/Programming.md deleted file mode 100644 index 1f2cfa542ff47e019dac01647d0c5da8cca1f72a..0000000000000000000000000000000000000000 --- a/Programming.md +++ /dev/null @@ -1,33 +0,0 @@ -# Collection of programming stuff - -## Dependencies - -* github.com/spf13/cobra: used for basic cli of gosdn, such as starting the daemon, get versioning info etc -* grpc -* ygot - -## Structure of the code - -main.go: main() function -nucleus/: core functionality of gosdn - -ygot (yang for go tools). -Checkout this in go: go get github.com/openconfig/ygot/ygot - -## Usefull things to know - -Regenerate gRPC code (https://grpc.io/docs/languages/go/quickstart/#regenerate-grpc-code) - -* ( cd ~/go/src/github.com/grpc-go/cmd/protoc-gen-go-grpc/ && go install . ) -* -protoc \ - --go_out=Mgrpc/service_config/service_config.proto=/internal/proto/grpc_service_config:. \ - --go-grpc_out=Mgrpc/service_config/service_config.proto=/internal/proto/grpc_service_config:. \ - --go_opt=paths=source_relative \ - --go-grpc_opt=paths=source_relative \ - cliInterface/gosdnCLI.proto - -Generate the ygot code: - -just type: go generate - diff --git a/README.md b/README.md index 9ae2bb61f864c4628a149bb02628fc3154ea475b..0835d28c90b8eaa7b033343d1d4a753e7a77824b 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# goSDN [](https://code.fbi.h-da.de/cocsn/gosdn/-/commits/master) [](https://code.fbi.h-da.de/cocsn/gosdn/-/commits/master) +# goSDN [](https://code.fbi.h-da.de/danet/gosdn/-/commits/master) [](https://code.fbi.h-da.de/danet/gosdn/-/commits/master) `goSDN` is a prototypical approach to build a model driven multi-vendor SDN controller. @@ -42,7 +42,7 @@ You can install the latest release of `goSDN` locally using the `go get` command ```sh > git config --global url."git@code.fbi.h-da.de:".insteadOf "https://code.fbi.h-da.de" > go env -w GOPRIVATE=code.fbi.h-da.de/cocsn/* -> go get code.fbi.h-da.de/cocsn/gosdn/cmd/gosdn +> go get code.fbi.h-da.de/danet/gosdn/cmd/gosdn ``` To install the development version you need to clone the repo and use `go install` to build and install the binary: @@ -54,7 +54,7 @@ To install the development version you need to clone the repo and use `go instal > git clone git@code.fbi.h-da.de:cocsn/gosdn.git # checkout the develop branch (or any other branch) -> cd $GOPATH/src/code.fbi.h-da.de/cocsn/gosdn +> cd $GOPATH/src/code.fbi.h-da.de/danet/gosdn > git checkout develop > go install ./cmd/gosdn ``` @@ -64,19 +64,16 @@ Now you can start `goSDN` locally using the `gosdn` command or [use the CLI](#us # Getting Started ## k8s -We have an instance of `goSDN` for each the latest master and current develop branch running on the department's k8s cluster. These endpoints can be accessed using the `gosdn cli` command. If anything breaks please file an [issue](https://code.fbi.h-da.de/cocsn/gosdn/-/issues/new). +We have an instance of `goSDN` for each the latest master and current develop branch running on the department's k8s cluster. These endpoints can be accessed using the `gosdn cli` command. If anything breaks please file an [issue](https://code.fbi.h-da.de/danet/gosdn/-/issues/new). ## Using the CLI -The `gosdn cli` command allows you to interact with a running `goSDN` controller. Use `gosdn help cli` to print the available commands and flags. - -## Example - -[](https://asciinema.org/a/dfrDlFQt5DPlG9HDyetdmeEW8) +The CLI for goSDN is provided as the separate `gosdnc` application. +Please refer to the [README](https://code.fbi.h-da.de/danet/gosdnc/-/blob/develop/README.md) there. # CI Status | Master | Develop | | ------ | ------ | -| [](https://code.fbi.h-da.de/cocsn/gosdn/-/commits/master) | [](https://code.fbi.h-da.de/cocsn/gosdn/-/commits/develop) | -| [](https://code.fbi.h-da.de/cocsn/gosdn/-/commits/master) | [](https://code.fbi.h-da.de/cocsn/gosdn/-/commits/develop) | +| [](https://code.fbi.h-da.de/danet/gosdn/-/commits/master) | [](https://code.fbi.h-da.de/danet/gosdn/-/commits/develop) | +| [](https://code.fbi.h-da.de/danet/gosdn/-/commits/master) | [](https://code.fbi.h-da.de/danet/gosdn/-/commits/develop) | diff --git a/api/apiIntegration_test.go b/api/apiIntegration_test.go new file mode 100644 index 0000000000000000000000000000000000000000..bfc67ae99751d91b17a2e0d3c2151f175f11d22b --- /dev/null +++ b/api/apiIntegration_test.go @@ -0,0 +1,125 @@ +package api + +import ( + "testing" + + "code.fbi.h-da.de/danet/api/go/gosdn/pnd" + tpb "code.fbi.h-da.de/danet/api/go/gosdn/transport" + "github.com/google/uuid" + guuid "github.com/google/uuid" + "github.com/spf13/viper" +) + +func TestApiIntegration(t *testing.T) { + // TDOO: Remove once openshift grpc support is available + t.Skip("skipped due to openshift limitations") + if testing.Short() { + t.Skip("skipping integration test") + } + tests := []struct { + name string + wantErr bool + }{ + { + name: "default", + wantErr: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + defer viper.Reset() + if err := Init(testAPIEndpoint); (err != nil) != tt.wantErr { + switch err.(type) { + case viper.ConfigFileNotFoundError: + default: + t.Errorf("gosdn cli init error = %v, wantErr %v", err, tt.wantErr) + return + } + } + cliPnd := viper.GetString("CLI_PND") + cliSbi := viper.GetString("CLI_SBI") + + suid, err := uuid.Parse(cliSbi) + if err != nil { + t.Error(err) + } + puid, err := uuid.Parse(cliPnd) + if err != nil { + t.Error(err) + } + + opt := &tpb.TransportOption{ + Address: testAddress, + Username: testUsername, + Password: testPassword, + TransportOption: &tpb.TransportOption_GnmiTransportOption{ + GnmiTransportOption: &tpb.GnmiTransportOption{}, + }, + } + if _, err := addDevice( + testAPIEndpoint, + "test-device", + opt, + suid, + puid, + ); (err != nil) != tt.wantErr { + t.Errorf("gosdn cli add-device error = %v, wantErr %v", err, tt.wantErr) + return + } + did := viper.GetString("LAST_DEVICE_UUID") + + _, err = getDevice( + testAPIEndpoint, + cliPnd, + did, + ) + if (err != nil) != tt.wantErr { + t.Errorf("gosdn cli request error = %v, wantErr %v", err, tt.wantErr) + return + } + + _, err = getDevice( + testAPIEndpoint, + cliPnd, + "", + did, + ) + if (err != nil) != tt.wantErr { + t.Errorf("gosdn cli get-device error = %v, wantErr %v", err, tt.wantErr) + return + } + + hostname := guuid.New().String() + _, err = changeRequest( + testAPIEndpoint, + did, + cliPnd, + testPath, + hostname, + pnd.ApiOperation_UPDATE, + ) + if (err != nil) != tt.wantErr { + t.Errorf("gosdn cli set error = %v, wantErr %v", err, tt.wantErr) + return + } + + resp, err := getDevice(testAddress, testUsername, testPassword, testPath) + if err != nil { + if !tt.wantErr { + t.Errorf("Get() error = %v, wantErr %v", err, tt.wantErr) + } + return + } + var got string + if resp != nil { + got = resp.Ond[0].Name + } else { + t.Errorf("integration test failed got cannot be nil") + } + if got != hostname { + t.Errorf("integration test failed = got: %v, want: %v", got, hostname) + } + }) + } +} diff --git a/api/api_test.go b/api/api_test.go new file mode 100644 index 0000000000000000000000000000000000000000..a3f722da0509f09585d713520a0274ec5a39c5ce --- /dev/null +++ b/api/api_test.go @@ -0,0 +1,131 @@ +package api + +import ( + "testing" + + ppb "code.fbi.h-da.de/danet/api/go/gosdn/pnd" + spb "code.fbi.h-da.de/danet/api/go/gosdn/southbound" + tpb "code.fbi.h-da.de/danet/api/go/gosdn/transport" + "code.fbi.h-da.de/danet/gosdn/nucleus" + log "github.com/sirupsen/logrus" + "github.com/spf13/viper" +) + +func Test_Init(t *testing.T) { + viper.SetConfigFile("./api_test.toml") + if err := Init(bufnet); err != nil { + t.Error(err) + } +} + +func Test_GetIds(t *testing.T) { + resp, err := GetIds(bufnet) + if err != nil { + t.Error(err) + return + } + log.Info(resp) +} + +func Test_AddPnd(t *testing.T) { + sbi := nucleus.NewSBI(spb.Type_OPENCONFIG) + resp, err := AddPnd(bufnet, "test", "test pnd", sbi.ID().String()) + if err != nil { + t.Error(err) + return + } + log.Info(resp) +} + +func Test_GetPnd(t *testing.T) { + resp, err := GetPnd(bufnet, pndID) + if err != nil { + t.Error(err) + return + } + got := resp.Pnd[0].Id + if got != pndID { + t.Errorf("PND ID is %v, expected %v", got, pndID) + } +} + +func Test_GetChanges(t *testing.T) { + resp, err := getChanges(bufnet, pndID) + if err != nil { + t.Error(err) + return + } + log.Info(resp) +} + +func Test_CommitConfirm(t *testing.T) { + resp, err := commit(bufnet, pndID, changeID) + if err != nil { + t.Error(err) + return + } + log.Info(resp) + + resp, err = confirm(bufnet, pndID, changeID) + if err != nil { + t.Error(err) + return + } + log.Info(resp) +} + +func Test_AddDevice(t *testing.T) { + opt := &tpb.TransportOption{ + Address: "test", + Username: "test", + Password: "test", + TransportOption: &tpb.TransportOption_GnmiTransportOption{ + GnmiTransportOption: &tpb.GnmiTransportOption{}, + }, + } + resp, err := addDevice(bufnet, "test", opt, sbiUUID, pndUUID) + if err != nil { + t.Error(err) + return + } + log.Info(resp) +} + +func Test_GetDevice(t *testing.T) { + resp, err := getDevice(bufnet, pndID, ondID) + if err != nil { + t.Error(err) + return + } + got := resp.Ond[0].Id + if got != ondID { + t.Errorf("PND ID is %v, expected %v", got, ondID) + } +} + +func Test_Update(t *testing.T) { + resp, err := changeRequest(bufnet, ondID, pndID, "", "", ppb.ApiOperation_UPDATE) + if err != nil { + t.Error(err) + return + } + log.Info(resp) +} + +func Test_Replace(t *testing.T) { + resp, err := changeRequest(bufnet, ondID, pndID, "", "", ppb.ApiOperation_REPLACE) + if err != nil { + t.Error(err) + return + } + log.Info(resp) +} + +func Test_Delete(t *testing.T) { + resp, err := changeRequest(bufnet, ondID, pndID, "", "", ppb.ApiOperation_DELETE) + if err != nil { + t.Error(err) + return + } + log.Info(resp) +} diff --git a/api/api_test.toml b/api/api_test.toml new file mode 100644 index 0000000000000000000000000000000000000000..fb66a37541a7332465914a8f0f5102e5ba4a49a4 --- /dev/null +++ b/api/api_test.toml @@ -0,0 +1 @@ +cli_pnd = "2043519e-46d1-4963-9a8e-d99007e104b8" diff --git a/api/grpc.go b/api/grpc.go new file mode 100644 index 0000000000000000000000000000000000000000..0ebdabb68a8eb9612494cc44f0f290080d153afb --- /dev/null +++ b/api/grpc.go @@ -0,0 +1,293 @@ +package api + +import ( + "context" + "errors" + "time" + + pb "code.fbi.h-da.de/danet/api/go/gosdn/core" + ppb "code.fbi.h-da.de/danet/api/go/gosdn/pnd" + spb "code.fbi.h-da.de/danet/api/go/gosdn/southbound" + tpb "code.fbi.h-da.de/danet/api/go/gosdn/transport" + nbi "code.fbi.h-da.de/danet/gosdn/northbound/client" + "github.com/google/uuid" + log "github.com/sirupsen/logrus" + "github.com/spf13/viper" + + "google.golang.org/grpc" +) + +var dialOptions []grpc.DialOption + +func init() { + dialOptions = []grpc.DialOption{ + grpc.WithInsecure(), + } +} + +// Init initialises the CLI client. +func Init(addr string) error { + ctx := context.Background() + resp, err := getAllCore(ctx, addr) + if err != nil { + return err + } + if len(resp.Pnd) > 0 { + pid := resp.Pnd[0].Id + viper.Set("CLI_PND", pid) + log.Infof("PND: %v", pid) + if len(resp.Pnd[0].Sbi) != 0 { + sbi := resp.Pnd[0].Sbi[0].Id + viper.Set("CLI_SBI", sbi) + log.Infof("SBI: %v", sbi) + } + } + return viper.WriteConfig() +} + +// GetIds requests all UUID information from the controller +func GetIds(addr string) ([]*ppb.PrincipalNetworkDomain, error) { + ctx := context.Background() + resp, err := getAllCore(ctx, addr) + if err != nil { + return nil, err + } + return resp.Pnd, nil +} + +func getAllCore(ctx context.Context, addr string) (*pb.GetResponse, error) { + coreClient, err := nbi.CoreClient(addr, dialOptions...) + if err != nil { + return nil, err + } + req := &pb.GetRequest{ + Timestamp: time.Now().UnixNano(), + All: true, + } + return coreClient.Get(ctx, req) +} + +// AddPnd takes a name, description and SBI UUID to create a new +// PrincipalNetworkDomain on the controller +func AddPnd(addr, name, description, sbi string) (*pb.SetResponse, error) { + coreClient, err := nbi.CoreClient(addr, dialOptions...) + if err != nil { + return nil, err + } + ctx := context.Background() + req := &pb.SetRequest{ + Timestamp: time.Now().UnixNano(), + Pnd: []*pb.SetPnd{ + { + Name: name, + Description: description, + Sbi: sbi, + }, + }, + } + + return coreClient.Set(ctx, req) +} + +// GetPnd requests one or several PrincipalNetworkDomains from the +// controller. To request all PrincipalNetworkDomains without providing +// names or UUIDs use GetIds() +func GetPnd(addr string, args ...string) (*pb.GetResponse, error) { + coreClient, err := nbi.CoreClient(addr, dialOptions...) + if err != nil { + return nil, err + } + if len(args) <= 0 { + return nil, errors.New("not enough arguments") + } + ctx := context.Background() + req := &pb.GetRequest{ + Timestamp: time.Now().UnixNano(), + Pid: args, + } + return coreClient.Get(ctx, req) +} + +// getChanges requests all pending and unconfirmed changes from the controller +func getChanges(addr, pnd string) (*ppb.GetResponse, error) { + ctx := context.Background() + client, err := nbi.PndClient(addr, dialOptions...) + if err != nil { + return nil, err + } + req := &ppb.GetRequest{ + Timestamp: time.Now().UnixNano(), + Request: &ppb.GetRequest_Change{ + Change: &ppb.GetChange{ + All: true, + }, + }, + Pid: pnd, + } + return client.Get(ctx, req) +} + +// commit sends a commit request for one or multiple changes to the +// controller. +func commit(addr, pnd string, cuids ...string) (*ppb.SetResponse, error) { + changes := make([]*ppb.SetChange, len(cuids)) + for i, arg := range cuids { + changes[i] = &ppb.SetChange{ + Cuid: arg, + Op: ppb.SetChange_COMMIT, + } + } + return commitConfirm(addr, pnd, changes) +} + +// confirm sends a confirm request for one or multiple changes to the +// controller +func confirm(addr, pnd string, cuids ...string) (*ppb.SetResponse, error) { + changes := make([]*ppb.SetChange, len(cuids)) + for i, arg := range cuids { + changes[i] = &ppb.SetChange{ + Cuid: arg, + Op: ppb.SetChange_CONFIRM, + } + } + return commitConfirm(addr, pnd, changes) +} + +func commitConfirm(addr, pnd string, changes []*ppb.SetChange) (*ppb.SetResponse, error) { + ctx := context.Background() + client, err := nbi.PndClient(addr, dialOptions...) + if err != nil { + return nil, err + } + req := &ppb.SetRequest{ + Timestamp: time.Now().UnixNano(), + Change: changes, + Pid: pnd, + } + return client.Set(ctx, req) +} + +// addDevice adds a new device to the controller. The device name is optional. +// If no name is provided a name will be generated upon device creation. +func addDevice(addr, deviceName string, opt *tpb.TransportOption, sid, pid uuid.UUID) (*ppb.SetResponse, error) { + pndClient, err := nbi.PndClient(addr, dialOptions...) + if err != nil { + return nil, err + } + + req := &ppb.SetRequest{ + Timestamp: time.Now().UnixNano(), + Ond: []*ppb.SetOnd{ + { + Address: opt.GetAddress(), + Sbi: &spb.SouthboundInterface{ + Id: sid.String(), + }, + DeviceName: deviceName, + TransportOption: opt, + }, + }, + Pid: pid.String(), + } + switch t := opt.Type; t { + case spb.Type_CONTAINERISED, spb.Type_PLUGIN: + req.Ond[0].Sbi.Id = uuid.Nil.String() + req.Ond[0].Sbi.Type = t + req.Ond[0].TransportOption.Type = t + default: + } + ctx := context.Background() + return pndClient.Set(ctx, req) +} + +// getDevice requests one or multiple devices belonging to a given +// PrincipalNetworkDomain from the controller. If no device identifier +// is provided, all devices are requested. +func getDevice(addr, pid string, did ...string) (*ppb.GetResponse, error) { + pndClient, err := nbi.PndClient(addr, dialOptions...) + if err != nil { + return nil, err + } + + var all bool + if len(did) == 0 { + all = true + } + + req := &ppb.GetRequest{ + Timestamp: time.Now().UnixNano(), + Request: &ppb.GetRequest_Ond{ + Ond: &ppb.GetOnd{ + All: all, + Did: did, + }, + }, + Pid: pid, + } + ctx := context.Background() + return pndClient.Get(ctx, req) +} + +func getPath(addr, pid, did, path string) (*ppb.GetResponse, error) { + pndClient, err := nbi.PndClient(addr, dialOptions...) + if err != nil { + return nil, err + } + + req := &ppb.GetRequest{ + Timestamp: time.Now().UnixNano(), + Request: &ppb.GetRequest_Path{ + Path: &ppb.GetPath{ + Did: did, + Path: path, + }, + }, + Pid: pid, + } + ctx := context.Background() + return pndClient.Get(ctx, req) +} + +func deleteDevice(addr, pid, did string) (*ppb.DeleteResponse, error) { + pndClient, err := nbi.PndClient(addr, dialOptions...) + if err != nil { + return nil, err + } + + req := &ppb.DeleteRequest{ + Timestamp: time.Now().UnixNano(), + Type: ppb.DeleteRequest_OND, + Uuid: did, + Pid: pid, + } + ctx := context.Background() + return pndClient.Delete(ctx, req) +} + +// change creates a ChangeRequest for the specified OND. ApiOperations are +// used to specify the type of the change (update, replace, delete as specified +// in https://github.com/openconfig/reference/blob/master/rpc/gnmi/gnmi-specification.md#34-modifying-state) +// For delete operations the value field needs to contain an empty string. +func changeRequest(addr, did, pid, path, value string, op ppb.ApiOperation) (*ppb.SetResponse, error) { + req := &ppb.ChangeRequest{ + Id: did, + Path: path, + Value: value, + ApiOp: op, + } + return sendChangeRequest(addr, pid, req) +} + +func sendChangeRequest(addr, pid string, req *ppb.ChangeRequest) (*ppb.SetResponse, error) { + pndClient, err := nbi.PndClient(addr, dialOptions...) + if err != nil { + return nil, err + } + ctx := context.Background() + r := &ppb.SetRequest{ + Timestamp: time.Now().UnixNano(), + ChangeRequest: []*ppb.ChangeRequest{req}, + Pid: pid, + } + return pndClient.Set(ctx, r) +} diff --git a/api/initialise_test.go b/api/initialise_test.go new file mode 100644 index 0000000000000000000000000000000000000000..347a20a806d1fd027468bbf25f9481048590f8fe --- /dev/null +++ b/api/initialise_test.go @@ -0,0 +1,181 @@ +package api + +import ( + "context" + "net" + "os" + "testing" + + "time" + + cpb "code.fbi.h-da.de/danet/api/go/gosdn/core" + ppb "code.fbi.h-da.de/danet/api/go/gosdn/pnd" + tpb "code.fbi.h-da.de/danet/api/go/gosdn/transport" + "code.fbi.h-da.de/danet/gosdn/config" + "code.fbi.h-da.de/danet/gosdn/mocks" + nbi "code.fbi.h-da.de/danet/gosdn/northbound/server" + "code.fbi.h-da.de/danet/gosdn/nucleus" + "code.fbi.h-da.de/danet/gosdn/nucleus/util/proto" + "code.fbi.h-da.de/danet/gosdn/store" + "code.fbi.h-da.de/danet/yang-models/generated/openconfig" + "github.com/google/uuid" + log "github.com/sirupsen/logrus" + "github.com/stretchr/testify/mock" + "google.golang.org/grpc" + "google.golang.org/grpc/test/bufconn" + + gpb "github.com/openconfig/gnmi/proto/gnmi" + pb "google.golang.org/protobuf/proto" +) + +/* +Based on this StackOverflow answer: https://stackoverflow.com/a/52080545/4378176 +*/ + +const bufSize = 1024 * 1024 +const bufnet = "bufnet" +const pndID = "2043519e-46d1-4963-9a8e-d99007e104b8" +const changeID = "0992d600-f7d4-4906-9559-409b04d59a5f" +const sbiID = "f6fd4b35-f039-4111-9156-5e4501bb8a5a" +const ondID = "7e0ed8cc-ebf5-46fa-9794-741494914883" + +var pndStore *store.PndStore +var sbiStore *store.SbiStore +var lis *bufconn.Listener +var pndUUID uuid.UUID +var sbiUUID uuid.UUID + +func bootstrapUnitTest() { + dialOptions = []grpc.DialOption{ + grpc.WithContextDialer(bufDialer), + grpc.WithInsecure(), + } + lis = bufconn.Listen(bufSize) + s := grpc.NewServer() + pndStore = store.NewPndStore() + sbiStore = store.NewSbiStore() + + changeUUID, err := uuid.Parse(changeID) + if err != nil { + log.Fatal(err) + } + + pndUUID, err = uuid.Parse(pndID) + if err != nil { + log.Fatal(err) + } + + sbiUUID, err = uuid.Parse(sbiID) + if err != nil { + log.Fatal(err) + } + + deviceUUID, err := uuid.Parse(ondID) + if err != nil { + log.Fatal(err) + } + + mockChange := &mocks.Change{} + mockChange.On("Age").Return(time.Hour) + mockChange.On("State").Return(ppb.Change_INCONSISTENT) + + mockPnd := mocks.NetworkDomain{} + mockPnd.On("ID").Return(pndUUID) + mockPnd.On("GetName").Return("test") + mockPnd.On("GetDescription").Return("test") + mockPnd.On("PendingChanges").Return([]uuid.UUID{changeUUID}) + mockPnd.On("CommittedChanges").Return([]uuid.UUID{changeUUID}) + mockPnd.On("GetChange", mock.Anything).Return(mockChange, nil) + mockPnd.On("AddDevice", mock.Anything, mock.Anything, mock.Anything).Return(nil) + mockPnd.On("GetDevice", mock.Anything).Return(&nucleus.CommonDevice{ + UUID: deviceUUID, + GoStruct: &openconfig.Device{}, + }, nil) + mockPnd.On("Commit", mock.Anything).Return(nil) + mockPnd.On("Confirm", mock.Anything).Return(nil) + mockPnd.On("Devices").Return([]uuid.UUID{deviceUUID}) + mockPnd.On("GetSBIs").Return(sbiStore) + mockPnd.On("ChangeOND", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(uuid.Nil, nil) + + if err := pndStore.Add(&mockPnd); err != nil { + log.Fatal(err) + } + northbound := nbi.NewNBI(pndStore) + cpb.RegisterCoreServer(s, northbound.Core) + ppb.RegisterPndServer(s, northbound.Pnd) + go func() { + if err := s.Serve(lis); err != nil { + log.Fatalf("Server exited with error: %v", err) + } + }() +} + +func bufDialer(context.Context, string) (net.Conn, error) { + return lis.Dial() +} + +const testPath = "/system/config/hostname" + +var testAddress = "141.100.70.170:6030" +var testAPIEndpoint = "gosdn-latest.apps.ocp.fbi.h-da.de" +var testUsername = "admin" +var testPassword = "arista" +var opt *tpb.TransportOption +var gnmiMessages map[string]pb.Message + +func TestMain(m *testing.M) { + bootstrapUnitTest() + bootstrapIntegrationTest() + os.Exit(m.Run()) +} + +func bootstrapIntegrationTest() { + log.SetLevel(config.LogLevel) + + addr := os.Getenv("CEOS_TEST_ENDPOINT") + if addr != "" { + testAddress = addr + log.Infof("CEOS_TEST_ENDPOINT set to %v", testAddress) + } + api := os.Getenv("GOSDN_TEST_API_ENDPOINT") + if api != "" { + testAPIEndpoint = api + log.Infof("GOSDN_TEST_API_ENDPOINT set to %v", testAPIEndpoint) + } + u := os.Getenv("GOSDN_TEST_USER") + if u != "" { + testUsername = u + log.Infof("GOSDN_TEST_USER set to %v", testUsername) + } + p := os.Getenv("GOSDN_TEST_PASSWORD") + if p != "" { + testPassword = p + log.Infof("GOSDN_TEST_PASSWORD set to %v", testPassword) + } + + gnmiMessages = map[string]pb.Message{ + "../test/proto/cap-resp-arista-ceos": &gpb.CapabilityResponse{}, + "../test/proto/req-full-node": &gpb.GetRequest{}, + "../test/proto/req-full-node-arista-ceos": &gpb.GetRequest{}, + "../test/proto/req-interfaces-arista-ceos": &gpb.GetRequest{}, + "../test/proto/req-interfaces-interface-arista-ceos": &gpb.GetRequest{}, + "../test/proto/req-interfaces-wildcard": &gpb.GetRequest{}, + "../test/proto/resp-full-node": &gpb.GetResponse{}, + "../test/proto/resp-full-node-arista-ceos": &gpb.GetResponse{}, + "../test/proto/resp-interfaces-arista-ceos": &gpb.GetResponse{}, + "../test/proto/resp-interfaces-interface-arista-ceos": &gpb.GetResponse{}, + "../test/proto/resp-interfaces-wildcard": &gpb.GetResponse{}, + "../test/proto/resp-set-system-config-hostname": &gpb.SetResponse{}, + } + for k, v := range gnmiMessages { + if err := proto.Read(k, v); err != nil { + log.Fatalf("error parsing %v: %v", k, err) + } + } + + opt = &tpb.TransportOption{ + Address: testAddress, + Username: testUsername, + Password: testPassword, + } +} diff --git a/api/pnd.go b/api/pnd.go new file mode 100644 index 0000000000000000000000000000000000000000..573869c22a47b134b2c80cb19d0170b1f9508634 --- /dev/null +++ b/api/pnd.go @@ -0,0 +1,218 @@ +package api + +import ( + ppb "code.fbi.h-da.de/danet/api/go/gosdn/pnd" + tpb "code.fbi.h-da.de/danet/api/go/gosdn/transport" + "code.fbi.h-da.de/danet/gosdn/interfaces/change" + "code.fbi.h-da.de/danet/gosdn/interfaces/device" + "code.fbi.h-da.de/danet/gosdn/interfaces/networkdomain" + "code.fbi.h-da.de/danet/gosdn/interfaces/southbound" + "code.fbi.h-da.de/danet/gosdn/interfaces/store" + "code.fbi.h-da.de/danet/gosdn/nucleus/errors" + "github.com/google/uuid" + log "github.com/sirupsen/logrus" + "google.golang.org/protobuf/proto" +) + +// PrincipalNetworkDomainAdapter is an API adapter to reflect the NetworkDomain +// interface +type PrincipalNetworkDomainAdapter struct { + id uuid.UUID + endpoint string +} + +// NewAdapter creates a PND Adapter. It requires a valid PND UUID and a reachable +// goSDN endpoint. +func NewAdapter(id, endpoint string) (networkdomain.NetworkDomain, error) { + pid, err := uuid.Parse(id) + if err != nil { + return nil, err + } + return &PrincipalNetworkDomainAdapter{ + id: pid, + endpoint: endpoint, + }, nil +} + +// Destroy destroys the PND Adapter. Currently not implemented +func (p *PrincipalNetworkDomainAdapter) Destroy() error { + return &errors.ErrNotYetImplemented{} +} + +// AddSbi adds an SBI to the PND Adapter. Currently not implemented +func (p *PrincipalNetworkDomainAdapter) AddSbi(s southbound.SouthboundInterface) error { + return &errors.ErrNotYetImplemented{} +} + +// RemoveSbi removes an SBI from the PND Adapter. Currently not implemented +func (p *PrincipalNetworkDomainAdapter) RemoveSbi(uuid.UUID) error { + return &errors.ErrNotYetImplemented{} +} + +// AddDevice adds a new device to the controller. The device name is optional. +// If no name is provided a name will be generated upon device creation. +func (p *PrincipalNetworkDomainAdapter) AddDevice(name string, opts *tpb.TransportOption, sid uuid.UUID) error { + resp, err := addDevice(p.endpoint, name, opts, sid, p.ID()) + if err != nil { + return err + } + log.Info(resp) + return nil +} + +// AddDeviceFromStore adds a new device from store to the controller. Currently not implemented +func (p *PrincipalNetworkDomainAdapter) AddDeviceFromStore(name string, did uuid.UUID, opts *tpb.TransportOption, sid uuid.UUID) error { + return &errors.ErrNotYetImplemented{} +} + +// GetDevice requests one or multiple devices belonging to a given +// PrincipalNetworkDomain from the controller. If no device identifier +// is provided, all devices are requested. +func (p *PrincipalNetworkDomainAdapter) GetDevice(identifier string) (device.Device, error) { + resp, err := getDevice(p.endpoint, p.id.String(), identifier) + if err != nil { + return nil, err + } + // TODO: Parse into device.Device + log.Info(resp) + return nil, nil +} + +// RemoveDevice removes a device from the PND Adapter +func (p *PrincipalNetworkDomainAdapter) RemoveDevice(did uuid.UUID) error { + resp, err := deleteDevice(p.endpoint, p.id.String(), did.String()) + if err != nil { + return err + } + log.Info(resp) + return nil +} + +// Devices sends an API call to the controller requesting the UUIDs of all +// registered devices. Returns nil. +func (p *PrincipalNetworkDomainAdapter) Devices() []uuid.UUID { + return nil +} + +// ChangeOND sends an API call to the controller requesting the creation of +// a change from the provided Operation, path and value. The Change is marked +// as Pending and times out after the specified timeout period +func (p *PrincipalNetworkDomainAdapter) ChangeOND(duid uuid.UUID, operation ppb.ApiOperation, path string, value ...string) (uuid.UUID, error) { + var v string + if len(value) != 0 { + v = value[0] + } + resp, err := changeRequest(p.endpoint, duid.String(), p.id.String(), path, v, operation) + if err != nil { + return uuid.Nil, err + } + log.Info(resp) + return uuid.Nil, err +} + +// Request sends an API call to the controller requesting the specified path +// for the specified device +func (p *PrincipalNetworkDomainAdapter) Request(did uuid.UUID, path string) (proto.Message, error) { + resp, err := getPath(p.endpoint, p.id.String(), did.String(), path) + if err != nil { + return nil, err + } + return resp, nil +} + +// RequestAll sends an API call to the controller requesting the specified path +// for all registered devices. Not yet implemented. +func (p *PrincipalNetworkDomainAdapter) RequestAll(string) error { + return &errors.ErrNotYetImplemented{} +} + +// GetName returns the PND Adapter's name +func (p *PrincipalNetworkDomainAdapter) GetName() string { + return "PND Adapter" +} + +// GetDescription returns the PND Adapter's description +func (p *PrincipalNetworkDomainAdapter) GetDescription() string { + return "PND Adapter" +} + +// MarshalDevice sends an API call to the controller requesting the specified +// device as JSON representation. Not yet implemented +func (p *PrincipalNetworkDomainAdapter) MarshalDevice(string) (string, error) { + return "", &errors.ErrNotYetImplemented{} +} + +// ContainsDevice sends an API call to the controller checking if a device +// with the given UUID is present. Not implemented, always returns false +func (p *PrincipalNetworkDomainAdapter) ContainsDevice(uuid.UUID) bool { + return false +} + +// GetSBIs sends an API call to the controller requesting the +// registered SBIs. Not implemented, always returns nil +func (p *PrincipalNetworkDomainAdapter) GetSBIs() store.Store { + return nil +} + +// ID returns the PND Adapter's UUID +func (p *PrincipalNetworkDomainAdapter) ID() uuid.UUID { + return p.id +} + +// PendingChanges sends an API call to the controller requesting +// the UUIDs of all pending changes +func (p *PrincipalNetworkDomainAdapter) PendingChanges() []uuid.UUID { + resp, err := getChanges(p.endpoint, p.id.String()) + if err != nil { + log.Error(err) + return nil + } + return filterChanges(ppb.Change_PENDING, resp) +} + +// CommittedChanges sends an API call to the controller requesting +// the UUIDs of all committed changes +func (p *PrincipalNetworkDomainAdapter) CommittedChanges() []uuid.UUID { + resp, err := getChanges(p.endpoint, p.id.String()) + if err != nil { + log.Error(err) + return nil + } + return filterChanges(ppb.Change_COMMITTED, resp) +} + +// GetChange sends an API call to the controller requesting the specified change +func (p *PrincipalNetworkDomainAdapter) GetChange(uuid.UUID) (change.Change, error) { + return nil, &errors.ErrNotYetImplemented{} +} + +// Commit sends an API call to the controller committing the specified change +func (p *PrincipalNetworkDomainAdapter) Commit(cuid uuid.UUID) error { + resp, err := commit(p.endpoint, p.id.String(), cuid.String()) + if err != nil { + return err + } + log.Info(resp) + return nil +} + +// Confirm sends an API call to the controller confirming the specified change +func (p *PrincipalNetworkDomainAdapter) Confirm(cuid uuid.UUID) error { + resp, err := confirm(p.endpoint, p.id.String(), cuid.String()) + if err != nil { + return err + } + log.Info(resp) + return nil +} + +func filterChanges(state ppb.Change_State, resp *ppb.GetResponse) []uuid.UUID { + changes := make([]uuid.UUID, 0) + for _, ch := range resp.Change { + if ch.State == state { + id, _ := uuid.Parse(ch.Id) + changes = append(changes, id) + } + } + return changes +} diff --git a/api/pnd_test.go b/api/pnd_test.go new file mode 100644 index 0000000000000000000000000000000000000000..62beb9281875b6ef5a3d3c68eb8e2dbc3ec2005c --- /dev/null +++ b/api/pnd_test.go @@ -0,0 +1,666 @@ +package api + +import ( + "reflect" + "testing" + + ppb "code.fbi.h-da.de/danet/api/go/gosdn/pnd" + tpb "code.fbi.h-da.de/danet/api/go/gosdn/transport" + "code.fbi.h-da.de/danet/gosdn/interfaces/change" + "code.fbi.h-da.de/danet/gosdn/interfaces/device" + "code.fbi.h-da.de/danet/gosdn/interfaces/networkdomain" + "code.fbi.h-da.de/danet/gosdn/interfaces/southbound" + "code.fbi.h-da.de/danet/gosdn/interfaces/store" + "github.com/google/uuid" +) + +func TestNewAdapter(t *testing.T) { + type args struct { + id string + endpoint string + } + tests := []struct { + name string + args args + want networkdomain.NetworkDomain + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := NewAdapter(tt.args.id, tt.args.endpoint) + if (err != nil) != tt.wantErr { + t.Errorf("NewAdapter() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("NewAdapter() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestPrincipalNetworkDomainAdapter_Destroy(t *testing.T) { + type fields struct { + id uuid.UUID + endpoint string + } + tests := []struct { + name string + fields fields + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &PrincipalNetworkDomainAdapter{ + id: tt.fields.id, + endpoint: tt.fields.endpoint, + } + if err := p.Destroy(); (err != nil) != tt.wantErr { + t.Errorf("PrincipalNetworkDomainAdapter.Destroy() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestPrincipalNetworkDomainAdapter_AddSbi(t *testing.T) { + type fields struct { + id uuid.UUID + endpoint string + } + type args struct { + s southbound.SouthboundInterface + } + tests := []struct { + name string + fields fields + args args + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &PrincipalNetworkDomainAdapter{ + id: tt.fields.id, + endpoint: tt.fields.endpoint, + } + if err := p.AddSbi(tt.args.s); (err != nil) != tt.wantErr { + t.Errorf("PrincipalNetworkDomainAdapter.AddSbi() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestPrincipalNetworkDomainAdapter_RemoveSbi(t *testing.T) { + type fields struct { + id uuid.UUID + endpoint string + } + type args struct { + in0 uuid.UUID + } + tests := []struct { + name string + fields fields + args args + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &PrincipalNetworkDomainAdapter{ + id: tt.fields.id, + endpoint: tt.fields.endpoint, + } + if err := p.RemoveSbi(tt.args.in0); (err != nil) != tt.wantErr { + t.Errorf("PrincipalNetworkDomainAdapter.RemoveSbi() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestPrincipalNetworkDomainAdapter_AddDevice(t *testing.T) { + type fields struct { + id uuid.UUID + endpoint string + } + type args struct { + name string + opts *tpb.TransportOption + sid uuid.UUID + } + tests := []struct { + name string + fields fields + args args + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &PrincipalNetworkDomainAdapter{ + id: tt.fields.id, + endpoint: tt.fields.endpoint, + } + if err := p.AddDevice(tt.args.name, tt.args.opts, tt.args.sid); (err != nil) != tt.wantErr { + t.Errorf("PrincipalNetworkDomainAdapter.AddDevice() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestPrincipalNetworkDomainAdapter_GetDevice(t *testing.T) { + type fields struct { + id uuid.UUID + endpoint string + } + type args struct { + identifier string + } + tests := []struct { + name string + fields fields + args args + want device.Device + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &PrincipalNetworkDomainAdapter{ + id: tt.fields.id, + endpoint: tt.fields.endpoint, + } + got, err := p.GetDevice(tt.args.identifier) + if (err != nil) != tt.wantErr { + t.Errorf("PrincipalNetworkDomainAdapter.GetDevice() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("PrincipalNetworkDomainAdapter.GetDevice() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestPrincipalNetworkDomainAdapter_RemoveDevice(t *testing.T) { + type fields struct { + id uuid.UUID + endpoint string + } + type args struct { + did uuid.UUID + } + tests := []struct { + name string + fields fields + args args + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &PrincipalNetworkDomainAdapter{ + id: tt.fields.id, + endpoint: tt.fields.endpoint, + } + if err := p.RemoveDevice(tt.args.did); (err != nil) != tt.wantErr { + t.Errorf("PrincipalNetworkDomainAdapter.RemoveDevice() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestPrincipalNetworkDomainAdapter_Devices(t *testing.T) { + type fields struct { + id uuid.UUID + endpoint string + } + tests := []struct { + name string + fields fields + want []uuid.UUID + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &PrincipalNetworkDomainAdapter{ + id: tt.fields.id, + endpoint: tt.fields.endpoint, + } + if got := p.Devices(); !reflect.DeepEqual(got, tt.want) { + t.Errorf("PrincipalNetworkDomainAdapter.Devices() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestPrincipalNetworkDomainAdapter_ChangeOND(t *testing.T) { + type fields struct { + id uuid.UUID + endpoint string + } + type args struct { + uuid uuid.UUID + operation ppb.ApiOperation + path string + value []string + } + tests := []struct { + name string + fields fields + args args + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &PrincipalNetworkDomainAdapter{ + id: tt.fields.id, + endpoint: tt.fields.endpoint, + } + _, err := p.ChangeOND(tt.args.uuid, tt.args.operation, tt.args.path, tt.args.value...) + if (err != nil) != tt.wantErr { + t.Errorf("PrincipalNetworkDomainAdapter.ChangeOND() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestPrincipalNetworkDomainAdapter_Request(t *testing.T) { + type fields struct { + id uuid.UUID + endpoint string + } + type args struct { + did uuid.UUID + path string + } + tests := []struct { + name string + fields fields + args args + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &PrincipalNetworkDomainAdapter{ + id: tt.fields.id, + endpoint: tt.fields.endpoint, + } + _, err := p.Request(tt.args.did, tt.args.path) + if (err != nil) != tt.wantErr { + t.Errorf("PrincipalNetworkDomainAdapter.Request() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestPrincipalNetworkDomainAdapter_RequestAll(t *testing.T) { + type fields struct { + id uuid.UUID + endpoint string + } + type args struct { + in0 string + } + tests := []struct { + name string + fields fields + args args + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &PrincipalNetworkDomainAdapter{ + id: tt.fields.id, + endpoint: tt.fields.endpoint, + } + if err := p.RequestAll(tt.args.in0); (err != nil) != tt.wantErr { + t.Errorf("PrincipalNetworkDomainAdapter.RequestAll() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestPrincipalNetworkDomainAdapter_GetName(t *testing.T) { + type fields struct { + id uuid.UUID + endpoint string + } + tests := []struct { + name string + fields fields + want string + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &PrincipalNetworkDomainAdapter{ + id: tt.fields.id, + endpoint: tt.fields.endpoint, + } + if got := p.GetName(); got != tt.want { + t.Errorf("PrincipalNetworkDomainAdapter.GetName() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestPrincipalNetworkDomainAdapter_GetDescription(t *testing.T) { + type fields struct { + id uuid.UUID + endpoint string + } + tests := []struct { + name string + fields fields + want string + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &PrincipalNetworkDomainAdapter{ + id: tt.fields.id, + endpoint: tt.fields.endpoint, + } + if got := p.GetDescription(); got != tt.want { + t.Errorf("PrincipalNetworkDomainAdapter.GetDescription() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestPrincipalNetworkDomainAdapter_MarshalDevice(t *testing.T) { + type fields struct { + id uuid.UUID + endpoint string + } + type args struct { + in0 string + } + tests := []struct { + name string + fields fields + args args + want string + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &PrincipalNetworkDomainAdapter{ + id: tt.fields.id, + endpoint: tt.fields.endpoint, + } + got, err := p.MarshalDevice(tt.args.in0) + if (err != nil) != tt.wantErr { + t.Errorf("PrincipalNetworkDomainAdapter.MarshalDevice() error = %v, wantErr %v", err, tt.wantErr) + return + } + if got != tt.want { + t.Errorf("PrincipalNetworkDomainAdapter.MarshalDevice() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestPrincipalNetworkDomainAdapter_ContainsDevice(t *testing.T) { + type fields struct { + id uuid.UUID + endpoint string + } + type args struct { + in0 uuid.UUID + } + tests := []struct { + name string + fields fields + args args + want bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &PrincipalNetworkDomainAdapter{ + id: tt.fields.id, + endpoint: tt.fields.endpoint, + } + if got := p.ContainsDevice(tt.args.in0); got != tt.want { + t.Errorf("PrincipalNetworkDomainAdapter.ContainsDevice() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestPrincipalNetworkDomainAdapter_GetSBIs(t *testing.T) { + type fields struct { + id uuid.UUID + endpoint string + } + tests := []struct { + name string + fields fields + want store.Store + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &PrincipalNetworkDomainAdapter{ + id: tt.fields.id, + endpoint: tt.fields.endpoint, + } + if got := p.GetSBIs(); !reflect.DeepEqual(got, tt.want) { + t.Errorf("PrincipalNetworkDomainAdapter.GetSBIs() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestPrincipalNetworkDomainAdapter_ID(t *testing.T) { + type fields struct { + id uuid.UUID + endpoint string + } + tests := []struct { + name string + fields fields + want uuid.UUID + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &PrincipalNetworkDomainAdapter{ + id: tt.fields.id, + endpoint: tt.fields.endpoint, + } + if got := p.ID(); !reflect.DeepEqual(got, tt.want) { + t.Errorf("PrincipalNetworkDomainAdapter.ID() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestPrincipalNetworkDomainAdapter_PendingChanges(t *testing.T) { + type fields struct { + id uuid.UUID + endpoint string + } + tests := []struct { + name string + fields fields + want []uuid.UUID + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &PrincipalNetworkDomainAdapter{ + id: tt.fields.id, + endpoint: tt.fields.endpoint, + } + if got := p.PendingChanges(); !reflect.DeepEqual(got, tt.want) { + t.Errorf("PrincipalNetworkDomainAdapter.PendingChanges() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestPrincipalNetworkDomainAdapter_CommittedChanges(t *testing.T) { + type fields struct { + id uuid.UUID + endpoint string + } + tests := []struct { + name string + fields fields + want []uuid.UUID + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &PrincipalNetworkDomainAdapter{ + id: tt.fields.id, + endpoint: tt.fields.endpoint, + } + if got := p.CommittedChanges(); !reflect.DeepEqual(got, tt.want) { + t.Errorf("PrincipalNetworkDomainAdapter.CommittedChanges() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestPrincipalNetworkDomainAdapter_GetChange(t *testing.T) { + type fields struct { + id uuid.UUID + endpoint string + } + type args struct { + in uuid.UUID + } + tests := []struct { + name string + fields fields + args args + want change.Change + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &PrincipalNetworkDomainAdapter{ + id: tt.fields.id, + endpoint: tt.fields.endpoint, + } + got, err := p.GetChange(tt.args.in) + if (err != nil) != tt.wantErr { + t.Errorf("PrincipalNetworkDomainAdapter.GetChange() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("PrincipalNetworkDomainAdapter.GetChange() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestPrincipalNetworkDomainAdapter_Commit(t *testing.T) { + type fields struct { + id uuid.UUID + endpoint string + } + type args struct { + cuid uuid.UUID + } + tests := []struct { + name string + fields fields + args args + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &PrincipalNetworkDomainAdapter{ + id: tt.fields.id, + endpoint: tt.fields.endpoint, + } + if err := p.Commit(tt.args.cuid); (err != nil) != tt.wantErr { + t.Errorf("PrincipalNetworkDomainAdapter.Commit() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestPrincipalNetworkDomainAdapter_Confirm(t *testing.T) { + type fields struct { + id uuid.UUID + endpoint string + } + type args struct { + cuid uuid.UUID + } + tests := []struct { + name string + fields fields + args args + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := &PrincipalNetworkDomainAdapter{ + id: tt.fields.id, + endpoint: tt.fields.endpoint, + } + if err := p.Confirm(tt.args.cuid); (err != nil) != tt.wantErr { + t.Errorf("PrincipalNetworkDomainAdapter.Confirm() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func Test_filterChanges(t *testing.T) { + type args struct { + state ppb.Change_State + resp *ppb.GetResponse + } + tests := []struct { + name string + args args + want []uuid.UUID + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := filterChanges(tt.args.state, tt.args.resp); !reflect.DeepEqual(got, tt.want) { + t.Errorf("filterChanges() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/api/proto/gitlab.fbi.h-da.de/cocsn/gosdn/enums.pb.go b/api/proto/gitlab.fbi.h-da.de/cocsn/gosdn/enums.pb.go deleted file mode 100644 index 2513966533fc00a4c1d7465c6e9a13d986eea507..0000000000000000000000000000000000000000 --- a/api/proto/gitlab.fbi.h-da.de/cocsn/gosdn/enums.pb.go +++ /dev/null @@ -1,151 +0,0 @@ -// openconfig.enums is generated by proto_generator as a protobuf -// representation of a YANG schema. -// -// Input schema modules: -// - ../yang-models/models/openconfig/release/models/interfaces/openconfig-interfaces.yang -// Include paths: -// - ../yang-models/models/... - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.25.0-devel -// protoc v3.13.0 -// source: openconfig/enums/enums.proto - -package gosdn - -import ( - proto "github.com/golang/protobuf/proto" - _ "github.com/openconfig/ygot/proto/yext" - _ "github.com/openconfig/ygot/proto/ywrapper" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// This is a compile-time assertion that a sufficiently up-to-date version -// of the legacy proto package is being used. -const _ = proto.ProtoPackageIsVersion4 - -// IETFInterfacesInterfaceType represents an enumerated type generated for the YANG identity interface-type. -type IETFInterfacesInterfaceType int32 - -const ( - IETFInterfacesInterfaceType_IETFINTERFACESINTERFACETYPE_UNSET IETFInterfacesInterfaceType = 0 -) - -// Enum value maps for IETFInterfacesInterfaceType. -var ( - IETFInterfacesInterfaceType_name = map[int32]string{ - 0: "IETFINTERFACESINTERFACETYPE_UNSET", - } - IETFInterfacesInterfaceType_value = map[string]int32{ - "IETFINTERFACESINTERFACETYPE_UNSET": 0, - } -) - -func (x IETFInterfacesInterfaceType) Enum() *IETFInterfacesInterfaceType { - p := new(IETFInterfacesInterfaceType) - *p = x - return p -} - -func (x IETFInterfacesInterfaceType) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (IETFInterfacesInterfaceType) Descriptor() protoreflect.EnumDescriptor { - return file_openconfig_enums_enums_proto_enumTypes[0].Descriptor() -} - -func (IETFInterfacesInterfaceType) Type() protoreflect.EnumType { - return &file_openconfig_enums_enums_proto_enumTypes[0] -} - -func (x IETFInterfacesInterfaceType) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use IETFInterfacesInterfaceType.Descriptor instead. -func (IETFInterfacesInterfaceType) EnumDescriptor() ([]byte, []int) { - return file_openconfig_enums_enums_proto_rawDescGZIP(), []int{0} -} - -var File_openconfig_enums_enums_proto protoreflect.FileDescriptor - -var file_openconfig_enums_enums_proto_rawDesc = []byte{ - 0x0a, 0x1c, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x65, 0x6e, 0x75, - 0x6d, 0x73, 0x2f, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x10, - 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, - 0x1a, 0x38, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, - 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x79, 0x67, 0x6f, 0x74, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2f, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2f, 0x79, 0x77, 0x72, 0x61, - 0x70, 0x70, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x30, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x2f, 0x79, 0x67, 0x6f, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x79, 0x65, 0x78, - 0x74, 0x2f, 0x79, 0x65, 0x78, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2a, 0x44, 0x0a, 0x1b, - 0x49, 0x45, 0x54, 0x46, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x49, 0x6e, - 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x25, 0x0a, 0x21, 0x49, - 0x45, 0x54, 0x46, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x46, 0x41, 0x43, 0x45, 0x53, 0x49, 0x4e, 0x54, - 0x45, 0x52, 0x46, 0x41, 0x43, 0x45, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x45, 0x54, - 0x10, 0x00, 0x42, 0x20, 0x5a, 0x1e, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x66, 0x62, 0x69, - 0x2e, 0x68, 0x2d, 0x64, 0x61, 0x2e, 0x64, 0x65, 0x2f, 0x63, 0x6f, 0x63, 0x73, 0x6e, 0x2f, 0x67, - 0x6f, 0x73, 0x64, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_openconfig_enums_enums_proto_rawDescOnce sync.Once - file_openconfig_enums_enums_proto_rawDescData = file_openconfig_enums_enums_proto_rawDesc -) - -func file_openconfig_enums_enums_proto_rawDescGZIP() []byte { - file_openconfig_enums_enums_proto_rawDescOnce.Do(func() { - file_openconfig_enums_enums_proto_rawDescData = protoimpl.X.CompressGZIP(file_openconfig_enums_enums_proto_rawDescData) - }) - return file_openconfig_enums_enums_proto_rawDescData -} - -var file_openconfig_enums_enums_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_openconfig_enums_enums_proto_goTypes = []interface{}{ - (IETFInterfacesInterfaceType)(0), // 0: openconfig.enums.IETFInterfacesInterfaceType -} -var file_openconfig_enums_enums_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_openconfig_enums_enums_proto_init() } -func file_openconfig_enums_enums_proto_init() { - if File_openconfig_enums_enums_proto != nil { - return - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_openconfig_enums_enums_proto_rawDesc, - NumEnums: 1, - NumMessages: 0, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_openconfig_enums_enums_proto_goTypes, - DependencyIndexes: file_openconfig_enums_enums_proto_depIdxs, - EnumInfos: file_openconfig_enums_enums_proto_enumTypes, - }.Build() - File_openconfig_enums_enums_proto = out.File - file_openconfig_enums_enums_proto_rawDesc = nil - file_openconfig_enums_enums_proto_goTypes = nil - file_openconfig_enums_enums_proto_depIdxs = nil -} diff --git a/api/proto/gitlab.fbi.h-da.de/cocsn/gosdn/openconfig.pb.go b/api/proto/gitlab.fbi.h-da.de/cocsn/gosdn/openconfig.pb.go deleted file mode 100644 index fda5833bb53a461835874bcff8b76a4140dc11c4..0000000000000000000000000000000000000000 --- a/api/proto/gitlab.fbi.h-da.de/cocsn/gosdn/openconfig.pb.go +++ /dev/null @@ -1,177 +0,0 @@ -// openconfig is generated by proto_generator as a protobuf -// representation of a YANG schema. -// -// Input schema modules: -// - ../yang-models/models/openconfig/release/models/interfaces/openconfig-interfaces.yang -// Include paths: -// - ../yang-models/models/... - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.25.0-devel -// protoc v3.13.0 -// source: openconfig/openconfig.proto - -package gosdn - -import ( - proto "github.com/golang/protobuf/proto" - _ "github.com/openconfig/ygot/proto/yext" - _ "github.com/openconfig/ygot/proto/ywrapper" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// This is a compile-time assertion that a sufficiently up-to-date version -// of the legacy proto package is being used. -const _ = proto.ProtoPackageIsVersion4 - -type Device struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Interfaces *Interfaces `protobuf:"bytes,85031486,opt,name=interfaces,proto3" json:"interfaces,omitempty"` -} - -func (x *Device) Reset() { - *x = Device{} - if protoimpl.UnsafeEnabled { - mi := &file_openconfig_openconfig_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Device) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Device) ProtoMessage() {} - -func (x *Device) ProtoReflect() protoreflect.Message { - mi := &file_openconfig_openconfig_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Device.ProtoReflect.Descriptor instead. -func (*Device) Descriptor() ([]byte, []int) { - return file_openconfig_openconfig_proto_rawDescGZIP(), []int{0} -} - -func (x *Device) GetInterfaces() *Interfaces { - if x != nil { - return x.Interfaces - } - return nil -} - -var File_openconfig_openconfig_proto protoreflect.FileDescriptor - -var file_openconfig_openconfig_proto_rawDesc = []byte{ - 0x0a, 0x1b, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x6f, 0x70, 0x65, - 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0a, 0x6f, - 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x38, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x2f, 0x79, 0x67, 0x6f, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x79, 0x77, 0x72, 0x61, - 0x70, 0x70, 0x65, 0x72, 0x2f, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x1a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x79, 0x67, 0x6f, 0x74, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x79, 0x65, 0x78, 0x74, 0x2f, 0x79, 0x65, 0x78, 0x74, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x3c, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x22, 0x69, 0x0a, 0x06, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5f, 0x0a, - 0x0a, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x18, 0xbe, 0xf4, 0xc5, 0x28, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x73, 0x42, 0x0e, 0x82, 0x41, 0x0b, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x73, 0x52, 0x0a, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x42, 0x20, - 0x5a, 0x1e, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x66, 0x62, 0x69, 0x2e, 0x68, 0x2d, 0x64, - 0x61, 0x2e, 0x64, 0x65, 0x2f, 0x63, 0x6f, 0x63, 0x73, 0x6e, 0x2f, 0x67, 0x6f, 0x73, 0x64, 0x6e, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_openconfig_openconfig_proto_rawDescOnce sync.Once - file_openconfig_openconfig_proto_rawDescData = file_openconfig_openconfig_proto_rawDesc -) - -func file_openconfig_openconfig_proto_rawDescGZIP() []byte { - file_openconfig_openconfig_proto_rawDescOnce.Do(func() { - file_openconfig_openconfig_proto_rawDescData = protoimpl.X.CompressGZIP(file_openconfig_openconfig_proto_rawDescData) - }) - return file_openconfig_openconfig_proto_rawDescData -} - -var file_openconfig_openconfig_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_openconfig_openconfig_proto_goTypes = []interface{}{ - (*Device)(nil), // 0: openconfig.Device - (*Interfaces)(nil), // 1: openconfig.openconfig_interfaces.Interfaces -} -var file_openconfig_openconfig_proto_depIdxs = []int32{ - 1, // 0: openconfig.Device.interfaces:type_name -> openconfig.openconfig_interfaces.Interfaces - 1, // [1:1] is the sub-list for method output_type - 1, // [1:1] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name -} - -func init() { file_openconfig_openconfig_proto_init() } -func file_openconfig_openconfig_proto_init() { - if File_openconfig_openconfig_proto != nil { - return - } - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_init() - if !protoimpl.UnsafeEnabled { - file_openconfig_openconfig_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Device); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_openconfig_openconfig_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_openconfig_openconfig_proto_goTypes, - DependencyIndexes: file_openconfig_openconfig_proto_depIdxs, - MessageInfos: file_openconfig_openconfig_proto_msgTypes, - }.Build() - File_openconfig_openconfig_proto = out.File - file_openconfig_openconfig_proto_rawDesc = nil - file_openconfig_openconfig_proto_goTypes = nil - file_openconfig_openconfig_proto_depIdxs = nil -} diff --git a/api/proto/gitlab.fbi.h-da.de/cocsn/gosdn/openconfig_interfaces.pb.go b/api/proto/gitlab.fbi.h-da.de/cocsn/gosdn/openconfig_interfaces.pb.go deleted file mode 100644 index 9802a14b71ad60f6bd5de8f298286a553d3a1c0e..0000000000000000000000000000000000000000 --- a/api/proto/gitlab.fbi.h-da.de/cocsn/gosdn/openconfig_interfaces.pb.go +++ /dev/null @@ -1,2622 +0,0 @@ -// openconfig.openconfig_interfaces is generated by proto_generator as a protobuf -// representation of a YANG schema. -// -// Input schema modules: -// - ../yang-models/models/openconfig/release/models/interfaces/openconfig-interfaces.yang -// Include paths: -// - ../yang-models/models/... - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.25.0-devel -// protoc v3.13.0 -// source: openconfig/openconfig_interfaces/openconfig_interfaces.proto - -package gosdn - -import ( - proto "github.com/golang/protobuf/proto" - _ "github.com/openconfig/ygot/proto/yext" - ywrapper "github.com/openconfig/ygot/proto/ywrapper" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// This is a compile-time assertion that a sufficiently up-to-date version -// of the legacy proto package is being used. -const _ = proto.ProtoPackageIsVersion4 - -type Interfaces_Interface_State_AdminStatus int32 - -const ( - Interfaces_Interface_State_ADMINSTATUS_UNSET Interfaces_Interface_State_AdminStatus = 0 - Interfaces_Interface_State_ADMINSTATUS_UP Interfaces_Interface_State_AdminStatus = 1 - Interfaces_Interface_State_ADMINSTATUS_DOWN Interfaces_Interface_State_AdminStatus = 2 - Interfaces_Interface_State_ADMINSTATUS_TESTING Interfaces_Interface_State_AdminStatus = 3 -) - -// Enum value maps for Interfaces_Interface_State_AdminStatus. -var ( - Interfaces_Interface_State_AdminStatus_name = map[int32]string{ - 0: "ADMINSTATUS_UNSET", - 1: "ADMINSTATUS_UP", - 2: "ADMINSTATUS_DOWN", - 3: "ADMINSTATUS_TESTING", - } - Interfaces_Interface_State_AdminStatus_value = map[string]int32{ - "ADMINSTATUS_UNSET": 0, - "ADMINSTATUS_UP": 1, - "ADMINSTATUS_DOWN": 2, - "ADMINSTATUS_TESTING": 3, - } -) - -func (x Interfaces_Interface_State_AdminStatus) Enum() *Interfaces_Interface_State_AdminStatus { - p := new(Interfaces_Interface_State_AdminStatus) - *p = x - return p -} - -func (x Interfaces_Interface_State_AdminStatus) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (Interfaces_Interface_State_AdminStatus) Descriptor() protoreflect.EnumDescriptor { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_enumTypes[0].Descriptor() -} - -func (Interfaces_Interface_State_AdminStatus) Type() protoreflect.EnumType { - return &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_enumTypes[0] -} - -func (x Interfaces_Interface_State_AdminStatus) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use Interfaces_Interface_State_AdminStatus.Descriptor instead. -func (Interfaces_Interface_State_AdminStatus) EnumDescriptor() ([]byte, []int) { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescGZIP(), []int{0, 0, 2, 0} -} - -type Interfaces_Interface_State_OperStatus int32 - -const ( - Interfaces_Interface_State_OPERSTATUS_UNSET Interfaces_Interface_State_OperStatus = 0 - Interfaces_Interface_State_OPERSTATUS_UP Interfaces_Interface_State_OperStatus = 2 - Interfaces_Interface_State_OPERSTATUS_DOWN Interfaces_Interface_State_OperStatus = 3 - Interfaces_Interface_State_OPERSTATUS_TESTING Interfaces_Interface_State_OperStatus = 4 - Interfaces_Interface_State_OPERSTATUS_UNKNOWN Interfaces_Interface_State_OperStatus = 5 - Interfaces_Interface_State_OPERSTATUS_DORMANT Interfaces_Interface_State_OperStatus = 6 - Interfaces_Interface_State_OPERSTATUS_NOT_PRESENT Interfaces_Interface_State_OperStatus = 7 - Interfaces_Interface_State_OPERSTATUS_LOWER_LAYER_DOWN Interfaces_Interface_State_OperStatus = 8 -) - -// Enum value maps for Interfaces_Interface_State_OperStatus. -var ( - Interfaces_Interface_State_OperStatus_name = map[int32]string{ - 0: "OPERSTATUS_UNSET", - 2: "OPERSTATUS_UP", - 3: "OPERSTATUS_DOWN", - 4: "OPERSTATUS_TESTING", - 5: "OPERSTATUS_UNKNOWN", - 6: "OPERSTATUS_DORMANT", - 7: "OPERSTATUS_NOT_PRESENT", - 8: "OPERSTATUS_LOWER_LAYER_DOWN", - } - Interfaces_Interface_State_OperStatus_value = map[string]int32{ - "OPERSTATUS_UNSET": 0, - "OPERSTATUS_UP": 2, - "OPERSTATUS_DOWN": 3, - "OPERSTATUS_TESTING": 4, - "OPERSTATUS_UNKNOWN": 5, - "OPERSTATUS_DORMANT": 6, - "OPERSTATUS_NOT_PRESENT": 7, - "OPERSTATUS_LOWER_LAYER_DOWN": 8, - } -) - -func (x Interfaces_Interface_State_OperStatus) Enum() *Interfaces_Interface_State_OperStatus { - p := new(Interfaces_Interface_State_OperStatus) - *p = x - return p -} - -func (x Interfaces_Interface_State_OperStatus) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (Interfaces_Interface_State_OperStatus) Descriptor() protoreflect.EnumDescriptor { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_enumTypes[1].Descriptor() -} - -func (Interfaces_Interface_State_OperStatus) Type() protoreflect.EnumType { - return &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_enumTypes[1] -} - -func (x Interfaces_Interface_State_OperStatus) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use Interfaces_Interface_State_OperStatus.Descriptor instead. -func (Interfaces_Interface_State_OperStatus) EnumDescriptor() ([]byte, []int) { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescGZIP(), []int{0, 0, 2, 1} -} - -type Interfaces_Interface_Subinterfaces_Subinterface_State_AdminStatus int32 - -const ( - Interfaces_Interface_Subinterfaces_Subinterface_State_ADMINSTATUS_UNSET Interfaces_Interface_Subinterfaces_Subinterface_State_AdminStatus = 0 - Interfaces_Interface_Subinterfaces_Subinterface_State_ADMINSTATUS_UP Interfaces_Interface_Subinterfaces_Subinterface_State_AdminStatus = 1 - Interfaces_Interface_Subinterfaces_Subinterface_State_ADMINSTATUS_DOWN Interfaces_Interface_Subinterfaces_Subinterface_State_AdminStatus = 2 - Interfaces_Interface_Subinterfaces_Subinterface_State_ADMINSTATUS_TESTING Interfaces_Interface_Subinterfaces_Subinterface_State_AdminStatus = 3 -) - -// Enum value maps for Interfaces_Interface_Subinterfaces_Subinterface_State_AdminStatus. -var ( - Interfaces_Interface_Subinterfaces_Subinterface_State_AdminStatus_name = map[int32]string{ - 0: "ADMINSTATUS_UNSET", - 1: "ADMINSTATUS_UP", - 2: "ADMINSTATUS_DOWN", - 3: "ADMINSTATUS_TESTING", - } - Interfaces_Interface_Subinterfaces_Subinterface_State_AdminStatus_value = map[string]int32{ - "ADMINSTATUS_UNSET": 0, - "ADMINSTATUS_UP": 1, - "ADMINSTATUS_DOWN": 2, - "ADMINSTATUS_TESTING": 3, - } -) - -func (x Interfaces_Interface_Subinterfaces_Subinterface_State_AdminStatus) Enum() *Interfaces_Interface_Subinterfaces_Subinterface_State_AdminStatus { - p := new(Interfaces_Interface_Subinterfaces_Subinterface_State_AdminStatus) - *p = x - return p -} - -func (x Interfaces_Interface_Subinterfaces_Subinterface_State_AdminStatus) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (Interfaces_Interface_Subinterfaces_Subinterface_State_AdminStatus) Descriptor() protoreflect.EnumDescriptor { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_enumTypes[2].Descriptor() -} - -func (Interfaces_Interface_Subinterfaces_Subinterface_State_AdminStatus) Type() protoreflect.EnumType { - return &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_enumTypes[2] -} - -func (x Interfaces_Interface_Subinterfaces_Subinterface_State_AdminStatus) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use Interfaces_Interface_Subinterfaces_Subinterface_State_AdminStatus.Descriptor instead. -func (Interfaces_Interface_Subinterfaces_Subinterface_State_AdminStatus) EnumDescriptor() ([]byte, []int) { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescGZIP(), []int{0, 0, 3, 0, 1, 0} -} - -type Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus int32 - -const ( - Interfaces_Interface_Subinterfaces_Subinterface_State_OPERSTATUS_UNSET Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus = 0 - Interfaces_Interface_Subinterfaces_Subinterface_State_OPERSTATUS_UP Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus = 2 - Interfaces_Interface_Subinterfaces_Subinterface_State_OPERSTATUS_DOWN Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus = 3 - Interfaces_Interface_Subinterfaces_Subinterface_State_OPERSTATUS_TESTING Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus = 4 - Interfaces_Interface_Subinterfaces_Subinterface_State_OPERSTATUS_UNKNOWN Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus = 5 - Interfaces_Interface_Subinterfaces_Subinterface_State_OPERSTATUS_DORMANT Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus = 6 - Interfaces_Interface_Subinterfaces_Subinterface_State_OPERSTATUS_NOT_PRESENT Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus = 7 - Interfaces_Interface_Subinterfaces_Subinterface_State_OPERSTATUS_LOWER_LAYER_DOWN Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus = 8 -) - -// Enum value maps for Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus. -var ( - Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus_name = map[int32]string{ - 0: "OPERSTATUS_UNSET", - 2: "OPERSTATUS_UP", - 3: "OPERSTATUS_DOWN", - 4: "OPERSTATUS_TESTING", - 5: "OPERSTATUS_UNKNOWN", - 6: "OPERSTATUS_DORMANT", - 7: "OPERSTATUS_NOT_PRESENT", - 8: "OPERSTATUS_LOWER_LAYER_DOWN", - } - Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus_value = map[string]int32{ - "OPERSTATUS_UNSET": 0, - "OPERSTATUS_UP": 2, - "OPERSTATUS_DOWN": 3, - "OPERSTATUS_TESTING": 4, - "OPERSTATUS_UNKNOWN": 5, - "OPERSTATUS_DORMANT": 6, - "OPERSTATUS_NOT_PRESENT": 7, - "OPERSTATUS_LOWER_LAYER_DOWN": 8, - } -) - -func (x Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus) Enum() *Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus { - p := new(Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus) - *p = x - return p -} - -func (x Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus) Descriptor() protoreflect.EnumDescriptor { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_enumTypes[3].Descriptor() -} - -func (Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus) Type() protoreflect.EnumType { - return &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_enumTypes[3] -} - -func (x Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus.Descriptor instead. -func (Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus) EnumDescriptor() ([]byte, []int) { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescGZIP(), []int{0, 0, 3, 0, 1, 1} -} - -type Interfaces struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Interface []*Interfaces_InterfaceKey `protobuf:"bytes,422482938,rep,name=interface,proto3" json:"interface,omitempty"` -} - -func (x *Interfaces) Reset() { - *x = Interfaces{} - if protoimpl.UnsafeEnabled { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Interfaces) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Interfaces) ProtoMessage() {} - -func (x *Interfaces) ProtoReflect() protoreflect.Message { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Interfaces.ProtoReflect.Descriptor instead. -func (*Interfaces) Descriptor() ([]byte, []int) { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescGZIP(), []int{0} -} - -func (x *Interfaces) GetInterface() []*Interfaces_InterfaceKey { - if x != nil { - return x.Interface - } - return nil -} - -type Interfaces_Interface struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Config *Interfaces_Interface_Config `protobuf:"bytes,334174827,opt,name=config,proto3" json:"config,omitempty"` - HoldTime *Interfaces_Interface_HoldTime `protobuf:"bytes,175931092,opt,name=hold_time,json=holdTime,proto3" json:"hold_time,omitempty"` - State *Interfaces_Interface_State `protobuf:"bytes,387556140,opt,name=state,proto3" json:"state,omitempty"` - Subinterfaces *Interfaces_Interface_Subinterfaces `protobuf:"bytes,327798165,opt,name=subinterfaces,proto3" json:"subinterfaces,omitempty"` -} - -func (x *Interfaces_Interface) Reset() { - *x = Interfaces_Interface{} - if protoimpl.UnsafeEnabled { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Interfaces_Interface) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Interfaces_Interface) ProtoMessage() {} - -func (x *Interfaces_Interface) ProtoReflect() protoreflect.Message { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Interfaces_Interface.ProtoReflect.Descriptor instead. -func (*Interfaces_Interface) Descriptor() ([]byte, []int) { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescGZIP(), []int{0, 0} -} - -func (x *Interfaces_Interface) GetConfig() *Interfaces_Interface_Config { - if x != nil { - return x.Config - } - return nil -} - -func (x *Interfaces_Interface) GetHoldTime() *Interfaces_Interface_HoldTime { - if x != nil { - return x.HoldTime - } - return nil -} - -func (x *Interfaces_Interface) GetState() *Interfaces_Interface_State { - if x != nil { - return x.State - } - return nil -} - -func (x *Interfaces_Interface) GetSubinterfaces() *Interfaces_Interface_Subinterfaces { - if x != nil { - return x.Subinterfaces - } - return nil -} - -type Interfaces_InterfaceKey struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Interface *Interfaces_Interface `protobuf:"bytes,2,opt,name=interface,proto3" json:"interface,omitempty"` -} - -func (x *Interfaces_InterfaceKey) Reset() { - *x = Interfaces_InterfaceKey{} - if protoimpl.UnsafeEnabled { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Interfaces_InterfaceKey) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Interfaces_InterfaceKey) ProtoMessage() {} - -func (x *Interfaces_InterfaceKey) ProtoReflect() protoreflect.Message { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Interfaces_InterfaceKey.ProtoReflect.Descriptor instead. -func (*Interfaces_InterfaceKey) Descriptor() ([]byte, []int) { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescGZIP(), []int{0, 1} -} - -func (x *Interfaces_InterfaceKey) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *Interfaces_InterfaceKey) GetInterface() *Interfaces_Interface { - if x != nil { - return x.Interface - } - return nil -} - -type Interfaces_Interface_Config struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Description *ywrapper.StringValue `protobuf:"bytes,418535860,opt,name=description,proto3" json:"description,omitempty"` - Enabled *ywrapper.BoolValue `protobuf:"bytes,37224301,opt,name=enabled,proto3" json:"enabled,omitempty"` - LoopbackMode *ywrapper.BoolValue `protobuf:"bytes,253516347,opt,name=loopback_mode,json=loopbackMode,proto3" json:"loopback_mode,omitempty"` - Mtu *ywrapper.UintValue `protobuf:"bytes,376210342,opt,name=mtu,proto3" json:"mtu,omitempty"` - Name *ywrapper.StringValue `protobuf:"bytes,51804187,opt,name=name,proto3" json:"name,omitempty"` - Type IETFInterfacesInterfaceType `protobuf:"varint,144596894,opt,name=type,proto3,enum=openconfig.enums.IETFInterfacesInterfaceType" json:"type,omitempty"` -} - -func (x *Interfaces_Interface_Config) Reset() { - *x = Interfaces_Interface_Config{} - if protoimpl.UnsafeEnabled { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Interfaces_Interface_Config) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Interfaces_Interface_Config) ProtoMessage() {} - -func (x *Interfaces_Interface_Config) ProtoReflect() protoreflect.Message { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Interfaces_Interface_Config.ProtoReflect.Descriptor instead. -func (*Interfaces_Interface_Config) Descriptor() ([]byte, []int) { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescGZIP(), []int{0, 0, 0} -} - -func (x *Interfaces_Interface_Config) GetDescription() *ywrapper.StringValue { - if x != nil { - return x.Description - } - return nil -} - -func (x *Interfaces_Interface_Config) GetEnabled() *ywrapper.BoolValue { - if x != nil { - return x.Enabled - } - return nil -} - -func (x *Interfaces_Interface_Config) GetLoopbackMode() *ywrapper.BoolValue { - if x != nil { - return x.LoopbackMode - } - return nil -} - -func (x *Interfaces_Interface_Config) GetMtu() *ywrapper.UintValue { - if x != nil { - return x.Mtu - } - return nil -} - -func (x *Interfaces_Interface_Config) GetName() *ywrapper.StringValue { - if x != nil { - return x.Name - } - return nil -} - -func (x *Interfaces_Interface_Config) GetType() IETFInterfacesInterfaceType { - if x != nil { - return x.Type - } - return IETFInterfacesInterfaceType_IETFINTERFACESINTERFACETYPE_UNSET -} - -type Interfaces_Interface_HoldTime struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Config *Interfaces_Interface_HoldTime_Config `protobuf:"bytes,316512729,opt,name=config,proto3" json:"config,omitempty"` - State *Interfaces_Interface_HoldTime_State `protobuf:"bytes,483010990,opt,name=state,proto3" json:"state,omitempty"` -} - -func (x *Interfaces_Interface_HoldTime) Reset() { - *x = Interfaces_Interface_HoldTime{} - if protoimpl.UnsafeEnabled { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Interfaces_Interface_HoldTime) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Interfaces_Interface_HoldTime) ProtoMessage() {} - -func (x *Interfaces_Interface_HoldTime) ProtoReflect() protoreflect.Message { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Interfaces_Interface_HoldTime.ProtoReflect.Descriptor instead. -func (*Interfaces_Interface_HoldTime) Descriptor() ([]byte, []int) { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescGZIP(), []int{0, 0, 1} -} - -func (x *Interfaces_Interface_HoldTime) GetConfig() *Interfaces_Interface_HoldTime_Config { - if x != nil { - return x.Config - } - return nil -} - -func (x *Interfaces_Interface_HoldTime) GetState() *Interfaces_Interface_HoldTime_State { - if x != nil { - return x.State - } - return nil -} - -type Interfaces_Interface_State struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - AdminStatus Interfaces_Interface_State_AdminStatus `protobuf:"varint,474494763,opt,name=admin_status,json=adminStatus,proto3,enum=openconfig.openconfig_interfaces.Interfaces_Interface_State_AdminStatus" json:"admin_status,omitempty"` - Counters *Interfaces_Interface_State_Counters `protobuf:"bytes,83645964,opt,name=counters,proto3" json:"counters,omitempty"` - Description *ywrapper.StringValue `protobuf:"bytes,389435287,opt,name=description,proto3" json:"description,omitempty"` - Enabled *ywrapper.BoolValue `protobuf:"bytes,330927518,opt,name=enabled,proto3" json:"enabled,omitempty"` - Ifindex *ywrapper.UintValue `protobuf:"bytes,116108202,opt,name=ifindex,proto3" json:"ifindex,omitempty"` - LastChange *ywrapper.UintValue `protobuf:"bytes,127348880,opt,name=last_change,json=lastChange,proto3" json:"last_change,omitempty"` - Logical *ywrapper.BoolValue `protobuf:"bytes,440460216,opt,name=logical,proto3" json:"logical,omitempty"` - LoopbackMode *ywrapper.BoolValue `protobuf:"bytes,372935512,opt,name=loopback_mode,json=loopbackMode,proto3" json:"loopback_mode,omitempty"` - Mtu *ywrapper.UintValue `protobuf:"bytes,96390485,opt,name=mtu,proto3" json:"mtu,omitempty"` - Name *ywrapper.StringValue `protobuf:"bytes,503495278,opt,name=name,proto3" json:"name,omitempty"` - OperStatus Interfaces_Interface_State_OperStatus `protobuf:"varint,470394226,opt,name=oper_status,json=operStatus,proto3,enum=openconfig.openconfig_interfaces.Interfaces_Interface_State_OperStatus" json:"oper_status,omitempty"` - Type IETFInterfacesInterfaceType `protobuf:"varint,358148579,opt,name=type,proto3,enum=openconfig.enums.IETFInterfacesInterfaceType" json:"type,omitempty"` -} - -func (x *Interfaces_Interface_State) Reset() { - *x = Interfaces_Interface_State{} - if protoimpl.UnsafeEnabled { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Interfaces_Interface_State) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Interfaces_Interface_State) ProtoMessage() {} - -func (x *Interfaces_Interface_State) ProtoReflect() protoreflect.Message { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Interfaces_Interface_State.ProtoReflect.Descriptor instead. -func (*Interfaces_Interface_State) Descriptor() ([]byte, []int) { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescGZIP(), []int{0, 0, 2} -} - -func (x *Interfaces_Interface_State) GetAdminStatus() Interfaces_Interface_State_AdminStatus { - if x != nil { - return x.AdminStatus - } - return Interfaces_Interface_State_ADMINSTATUS_UNSET -} - -func (x *Interfaces_Interface_State) GetCounters() *Interfaces_Interface_State_Counters { - if x != nil { - return x.Counters - } - return nil -} - -func (x *Interfaces_Interface_State) GetDescription() *ywrapper.StringValue { - if x != nil { - return x.Description - } - return nil -} - -func (x *Interfaces_Interface_State) GetEnabled() *ywrapper.BoolValue { - if x != nil { - return x.Enabled - } - return nil -} - -func (x *Interfaces_Interface_State) GetIfindex() *ywrapper.UintValue { - if x != nil { - return x.Ifindex - } - return nil -} - -func (x *Interfaces_Interface_State) GetLastChange() *ywrapper.UintValue { - if x != nil { - return x.LastChange - } - return nil -} - -func (x *Interfaces_Interface_State) GetLogical() *ywrapper.BoolValue { - if x != nil { - return x.Logical - } - return nil -} - -func (x *Interfaces_Interface_State) GetLoopbackMode() *ywrapper.BoolValue { - if x != nil { - return x.LoopbackMode - } - return nil -} - -func (x *Interfaces_Interface_State) GetMtu() *ywrapper.UintValue { - if x != nil { - return x.Mtu - } - return nil -} - -func (x *Interfaces_Interface_State) GetName() *ywrapper.StringValue { - if x != nil { - return x.Name - } - return nil -} - -func (x *Interfaces_Interface_State) GetOperStatus() Interfaces_Interface_State_OperStatus { - if x != nil { - return x.OperStatus - } - return Interfaces_Interface_State_OPERSTATUS_UNSET -} - -func (x *Interfaces_Interface_State) GetType() IETFInterfacesInterfaceType { - if x != nil { - return x.Type - } - return IETFInterfacesInterfaceType_IETFINTERFACESINTERFACETYPE_UNSET -} - -type Interfaces_Interface_Subinterfaces struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Subinterface []*Interfaces_Interface_Subinterfaces_SubinterfaceKey `protobuf:"bytes,464802819,rep,name=subinterface,proto3" json:"subinterface,omitempty"` -} - -func (x *Interfaces_Interface_Subinterfaces) Reset() { - *x = Interfaces_Interface_Subinterfaces{} - if protoimpl.UnsafeEnabled { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Interfaces_Interface_Subinterfaces) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Interfaces_Interface_Subinterfaces) ProtoMessage() {} - -func (x *Interfaces_Interface_Subinterfaces) ProtoReflect() protoreflect.Message { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Interfaces_Interface_Subinterfaces.ProtoReflect.Descriptor instead. -func (*Interfaces_Interface_Subinterfaces) Descriptor() ([]byte, []int) { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescGZIP(), []int{0, 0, 3} -} - -func (x *Interfaces_Interface_Subinterfaces) GetSubinterface() []*Interfaces_Interface_Subinterfaces_SubinterfaceKey { - if x != nil { - return x.Subinterface - } - return nil -} - -type Interfaces_Interface_HoldTime_Config struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Down *ywrapper.UintValue `protobuf:"bytes,171181656,opt,name=down,proto3" json:"down,omitempty"` - Up *ywrapper.UintValue `protobuf:"bytes,62026235,opt,name=up,proto3" json:"up,omitempty"` -} - -func (x *Interfaces_Interface_HoldTime_Config) Reset() { - *x = Interfaces_Interface_HoldTime_Config{} - if protoimpl.UnsafeEnabled { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Interfaces_Interface_HoldTime_Config) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Interfaces_Interface_HoldTime_Config) ProtoMessage() {} - -func (x *Interfaces_Interface_HoldTime_Config) ProtoReflect() protoreflect.Message { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Interfaces_Interface_HoldTime_Config.ProtoReflect.Descriptor instead. -func (*Interfaces_Interface_HoldTime_Config) Descriptor() ([]byte, []int) { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescGZIP(), []int{0, 0, 1, 0} -} - -func (x *Interfaces_Interface_HoldTime_Config) GetDown() *ywrapper.UintValue { - if x != nil { - return x.Down - } - return nil -} - -func (x *Interfaces_Interface_HoldTime_Config) GetUp() *ywrapper.UintValue { - if x != nil { - return x.Up - } - return nil -} - -type Interfaces_Interface_HoldTime_State struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Down *ywrapper.UintValue `protobuf:"bytes,167887721,opt,name=down,proto3" json:"down,omitempty"` - Up *ywrapper.UintValue `protobuf:"bytes,223847598,opt,name=up,proto3" json:"up,omitempty"` -} - -func (x *Interfaces_Interface_HoldTime_State) Reset() { - *x = Interfaces_Interface_HoldTime_State{} - if protoimpl.UnsafeEnabled { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Interfaces_Interface_HoldTime_State) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Interfaces_Interface_HoldTime_State) ProtoMessage() {} - -func (x *Interfaces_Interface_HoldTime_State) ProtoReflect() protoreflect.Message { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Interfaces_Interface_HoldTime_State.ProtoReflect.Descriptor instead. -func (*Interfaces_Interface_HoldTime_State) Descriptor() ([]byte, []int) { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescGZIP(), []int{0, 0, 1, 1} -} - -func (x *Interfaces_Interface_HoldTime_State) GetDown() *ywrapper.UintValue { - if x != nil { - return x.Down - } - return nil -} - -func (x *Interfaces_Interface_HoldTime_State) GetUp() *ywrapper.UintValue { - if x != nil { - return x.Up - } - return nil -} - -type Interfaces_Interface_State_Counters struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - CarrierTransitions *ywrapper.UintValue `protobuf:"bytes,270803130,opt,name=carrier_transitions,json=carrierTransitions,proto3" json:"carrier_transitions,omitempty"` - InBroadcastPkts *ywrapper.UintValue `protobuf:"bytes,280201989,opt,name=in_broadcast_pkts,json=inBroadcastPkts,proto3" json:"in_broadcast_pkts,omitempty"` - InDiscards *ywrapper.UintValue `protobuf:"bytes,11979514,opt,name=in_discards,json=inDiscards,proto3" json:"in_discards,omitempty"` - InErrors *ywrapper.UintValue `protobuf:"bytes,456697578,opt,name=in_errors,json=inErrors,proto3" json:"in_errors,omitempty"` - InFcsErrors *ywrapper.UintValue `protobuf:"bytes,501559027,opt,name=in_fcs_errors,json=inFcsErrors,proto3" json:"in_fcs_errors,omitempty"` - InMulticastPkts *ywrapper.UintValue `protobuf:"bytes,113269128,opt,name=in_multicast_pkts,json=inMulticastPkts,proto3" json:"in_multicast_pkts,omitempty"` - InOctets *ywrapper.UintValue `protobuf:"bytes,333138891,opt,name=in_octets,json=inOctets,proto3" json:"in_octets,omitempty"` - InPkts *ywrapper.UintValue `protobuf:"bytes,412843491,opt,name=in_pkts,json=inPkts,proto3" json:"in_pkts,omitempty"` - InUnicastPkts *ywrapper.UintValue `protobuf:"bytes,272792307,opt,name=in_unicast_pkts,json=inUnicastPkts,proto3" json:"in_unicast_pkts,omitempty"` - InUnknownProtos *ywrapper.UintValue `protobuf:"bytes,241475497,opt,name=in_unknown_protos,json=inUnknownProtos,proto3" json:"in_unknown_protos,omitempty"` - LastClear *ywrapper.UintValue `protobuf:"bytes,186014919,opt,name=last_clear,json=lastClear,proto3" json:"last_clear,omitempty"` - OutBroadcastPkts *ywrapper.UintValue `protobuf:"bytes,338589668,opt,name=out_broadcast_pkts,json=outBroadcastPkts,proto3" json:"out_broadcast_pkts,omitempty"` - OutDiscards *ywrapper.UintValue `protobuf:"bytes,254055111,opt,name=out_discards,json=outDiscards,proto3" json:"out_discards,omitempty"` - OutErrors *ywrapper.UintValue `protobuf:"bytes,471103047,opt,name=out_errors,json=outErrors,proto3" json:"out_errors,omitempty"` - OutMulticastPkts *ywrapper.UintValue `protobuf:"bytes,457840757,opt,name=out_multicast_pkts,json=outMulticastPkts,proto3" json:"out_multicast_pkts,omitempty"` - OutOctets *ywrapper.UintValue `protobuf:"bytes,201005514,opt,name=out_octets,json=outOctets,proto3" json:"out_octets,omitempty"` - OutPkts *ywrapper.UintValue `protobuf:"bytes,437582090,opt,name=out_pkts,json=outPkts,proto3" json:"out_pkts,omitempty"` - OutUnicastPkts *ywrapper.UintValue `protobuf:"bytes,36542246,opt,name=out_unicast_pkts,json=outUnicastPkts,proto3" json:"out_unicast_pkts,omitempty"` -} - -func (x *Interfaces_Interface_State_Counters) Reset() { - *x = Interfaces_Interface_State_Counters{} - if protoimpl.UnsafeEnabled { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Interfaces_Interface_State_Counters) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Interfaces_Interface_State_Counters) ProtoMessage() {} - -func (x *Interfaces_Interface_State_Counters) ProtoReflect() protoreflect.Message { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Interfaces_Interface_State_Counters.ProtoReflect.Descriptor instead. -func (*Interfaces_Interface_State_Counters) Descriptor() ([]byte, []int) { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescGZIP(), []int{0, 0, 2, 0} -} - -func (x *Interfaces_Interface_State_Counters) GetCarrierTransitions() *ywrapper.UintValue { - if x != nil { - return x.CarrierTransitions - } - return nil -} - -func (x *Interfaces_Interface_State_Counters) GetInBroadcastPkts() *ywrapper.UintValue { - if x != nil { - return x.InBroadcastPkts - } - return nil -} - -func (x *Interfaces_Interface_State_Counters) GetInDiscards() *ywrapper.UintValue { - if x != nil { - return x.InDiscards - } - return nil -} - -func (x *Interfaces_Interface_State_Counters) GetInErrors() *ywrapper.UintValue { - if x != nil { - return x.InErrors - } - return nil -} - -func (x *Interfaces_Interface_State_Counters) GetInFcsErrors() *ywrapper.UintValue { - if x != nil { - return x.InFcsErrors - } - return nil -} - -func (x *Interfaces_Interface_State_Counters) GetInMulticastPkts() *ywrapper.UintValue { - if x != nil { - return x.InMulticastPkts - } - return nil -} - -func (x *Interfaces_Interface_State_Counters) GetInOctets() *ywrapper.UintValue { - if x != nil { - return x.InOctets - } - return nil -} - -func (x *Interfaces_Interface_State_Counters) GetInPkts() *ywrapper.UintValue { - if x != nil { - return x.InPkts - } - return nil -} - -func (x *Interfaces_Interface_State_Counters) GetInUnicastPkts() *ywrapper.UintValue { - if x != nil { - return x.InUnicastPkts - } - return nil -} - -func (x *Interfaces_Interface_State_Counters) GetInUnknownProtos() *ywrapper.UintValue { - if x != nil { - return x.InUnknownProtos - } - return nil -} - -func (x *Interfaces_Interface_State_Counters) GetLastClear() *ywrapper.UintValue { - if x != nil { - return x.LastClear - } - return nil -} - -func (x *Interfaces_Interface_State_Counters) GetOutBroadcastPkts() *ywrapper.UintValue { - if x != nil { - return x.OutBroadcastPkts - } - return nil -} - -func (x *Interfaces_Interface_State_Counters) GetOutDiscards() *ywrapper.UintValue { - if x != nil { - return x.OutDiscards - } - return nil -} - -func (x *Interfaces_Interface_State_Counters) GetOutErrors() *ywrapper.UintValue { - if x != nil { - return x.OutErrors - } - return nil -} - -func (x *Interfaces_Interface_State_Counters) GetOutMulticastPkts() *ywrapper.UintValue { - if x != nil { - return x.OutMulticastPkts - } - return nil -} - -func (x *Interfaces_Interface_State_Counters) GetOutOctets() *ywrapper.UintValue { - if x != nil { - return x.OutOctets - } - return nil -} - -func (x *Interfaces_Interface_State_Counters) GetOutPkts() *ywrapper.UintValue { - if x != nil { - return x.OutPkts - } - return nil -} - -func (x *Interfaces_Interface_State_Counters) GetOutUnicastPkts() *ywrapper.UintValue { - if x != nil { - return x.OutUnicastPkts - } - return nil -} - -type Interfaces_Interface_Subinterfaces_Subinterface struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Config *Interfaces_Interface_Subinterfaces_Subinterface_Config `protobuf:"bytes,175001476,opt,name=config,proto3" json:"config,omitempty"` - State *Interfaces_Interface_Subinterfaces_Subinterface_State `protobuf:"bytes,501974173,opt,name=state,proto3" json:"state,omitempty"` -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface) Reset() { - *x = Interfaces_Interface_Subinterfaces_Subinterface{} - if protoimpl.UnsafeEnabled { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Interfaces_Interface_Subinterfaces_Subinterface) ProtoMessage() {} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface) ProtoReflect() protoreflect.Message { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Interfaces_Interface_Subinterfaces_Subinterface.ProtoReflect.Descriptor instead. -func (*Interfaces_Interface_Subinterfaces_Subinterface) Descriptor() ([]byte, []int) { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescGZIP(), []int{0, 0, 3, 0} -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface) GetConfig() *Interfaces_Interface_Subinterfaces_Subinterface_Config { - if x != nil { - return x.Config - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface) GetState() *Interfaces_Interface_Subinterfaces_Subinterface_State { - if x != nil { - return x.State - } - return nil -} - -type Interfaces_Interface_Subinterfaces_SubinterfaceKey struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Index uint64 `protobuf:"varint,1,opt,name=index,proto3" json:"index,omitempty"` - Subinterface *Interfaces_Interface_Subinterfaces_Subinterface `protobuf:"bytes,2,opt,name=subinterface,proto3" json:"subinterface,omitempty"` -} - -func (x *Interfaces_Interface_Subinterfaces_SubinterfaceKey) Reset() { - *x = Interfaces_Interface_Subinterfaces_SubinterfaceKey{} - if protoimpl.UnsafeEnabled { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Interfaces_Interface_Subinterfaces_SubinterfaceKey) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Interfaces_Interface_Subinterfaces_SubinterfaceKey) ProtoMessage() {} - -func (x *Interfaces_Interface_Subinterfaces_SubinterfaceKey) ProtoReflect() protoreflect.Message { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[11] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Interfaces_Interface_Subinterfaces_SubinterfaceKey.ProtoReflect.Descriptor instead. -func (*Interfaces_Interface_Subinterfaces_SubinterfaceKey) Descriptor() ([]byte, []int) { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescGZIP(), []int{0, 0, 3, 1} -} - -func (x *Interfaces_Interface_Subinterfaces_SubinterfaceKey) GetIndex() uint64 { - if x != nil { - return x.Index - } - return 0 -} - -func (x *Interfaces_Interface_Subinterfaces_SubinterfaceKey) GetSubinterface() *Interfaces_Interface_Subinterfaces_Subinterface { - if x != nil { - return x.Subinterface - } - return nil -} - -type Interfaces_Interface_Subinterfaces_Subinterface_Config struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Description *ywrapper.StringValue `protobuf:"bytes,280671199,opt,name=description,proto3" json:"description,omitempty"` - Enabled *ywrapper.BoolValue `protobuf:"bytes,297236390,opt,name=enabled,proto3" json:"enabled,omitempty"` - Index *ywrapper.UintValue `protobuf:"bytes,279269781,opt,name=index,proto3" json:"index,omitempty"` -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_Config) Reset() { - *x = Interfaces_Interface_Subinterfaces_Subinterface_Config{} - if protoimpl.UnsafeEnabled { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_Config) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Interfaces_Interface_Subinterfaces_Subinterface_Config) ProtoMessage() {} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_Config) ProtoReflect() protoreflect.Message { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[12] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Interfaces_Interface_Subinterfaces_Subinterface_Config.ProtoReflect.Descriptor instead. -func (*Interfaces_Interface_Subinterfaces_Subinterface_Config) Descriptor() ([]byte, []int) { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescGZIP(), []int{0, 0, 3, 0, 0} -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_Config) GetDescription() *ywrapper.StringValue { - if x != nil { - return x.Description - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_Config) GetEnabled() *ywrapper.BoolValue { - if x != nil { - return x.Enabled - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_Config) GetIndex() *ywrapper.UintValue { - if x != nil { - return x.Index - } - return nil -} - -type Interfaces_Interface_Subinterfaces_Subinterface_State struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - AdminStatus Interfaces_Interface_Subinterfaces_Subinterface_State_AdminStatus `protobuf:"varint,250658952,opt,name=admin_status,json=adminStatus,proto3,enum=openconfig.openconfig_interfaces.Interfaces_Interface_Subinterfaces_Subinterface_State_AdminStatus" json:"admin_status,omitempty"` - Counters *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters `protobuf:"bytes,483442783,opt,name=counters,proto3" json:"counters,omitempty"` - Description *ywrapper.StringValue `protobuf:"bytes,49943526,opt,name=description,proto3" json:"description,omitempty"` - Enabled *ywrapper.BoolValue `protobuf:"bytes,468513843,opt,name=enabled,proto3" json:"enabled,omitempty"` - Ifindex *ywrapper.UintValue `protobuf:"bytes,511987815,opt,name=ifindex,proto3" json:"ifindex,omitempty"` - Index *ywrapper.UintValue `protobuf:"bytes,80745756,opt,name=index,proto3" json:"index,omitempty"` - LastChange *ywrapper.UintValue `protobuf:"bytes,29904521,opt,name=last_change,json=lastChange,proto3" json:"last_change,omitempty"` - Logical *ywrapper.BoolValue `protobuf:"bytes,294124401,opt,name=logical,proto3" json:"logical,omitempty"` - Name *ywrapper.StringValue `protobuf:"bytes,279346681,opt,name=name,proto3" json:"name,omitempty"` - OperStatus Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus `protobuf:"varint,401969247,opt,name=oper_status,json=operStatus,proto3,enum=openconfig.openconfig_interfaces.Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus" json:"oper_status,omitempty"` -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State) Reset() { - *x = Interfaces_Interface_Subinterfaces_Subinterface_State{} - if protoimpl.UnsafeEnabled { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Interfaces_Interface_Subinterfaces_Subinterface_State) ProtoMessage() {} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State) ProtoReflect() protoreflect.Message { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[13] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Interfaces_Interface_Subinterfaces_Subinterface_State.ProtoReflect.Descriptor instead. -func (*Interfaces_Interface_Subinterfaces_Subinterface_State) Descriptor() ([]byte, []int) { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescGZIP(), []int{0, 0, 3, 0, 1} -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State) GetAdminStatus() Interfaces_Interface_Subinterfaces_Subinterface_State_AdminStatus { - if x != nil { - return x.AdminStatus - } - return Interfaces_Interface_Subinterfaces_Subinterface_State_ADMINSTATUS_UNSET -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State) GetCounters() *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters { - if x != nil { - return x.Counters - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State) GetDescription() *ywrapper.StringValue { - if x != nil { - return x.Description - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State) GetEnabled() *ywrapper.BoolValue { - if x != nil { - return x.Enabled - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State) GetIfindex() *ywrapper.UintValue { - if x != nil { - return x.Ifindex - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State) GetIndex() *ywrapper.UintValue { - if x != nil { - return x.Index - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State) GetLastChange() *ywrapper.UintValue { - if x != nil { - return x.LastChange - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State) GetLogical() *ywrapper.BoolValue { - if x != nil { - return x.Logical - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State) GetName() *ywrapper.StringValue { - if x != nil { - return x.Name - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State) GetOperStatus() Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus { - if x != nil { - return x.OperStatus - } - return Interfaces_Interface_Subinterfaces_Subinterface_State_OPERSTATUS_UNSET -} - -type Interfaces_Interface_Subinterfaces_Subinterface_State_Counters struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - CarrierTransitions *ywrapper.UintValue `protobuf:"bytes,141120277,opt,name=carrier_transitions,json=carrierTransitions,proto3" json:"carrier_transitions,omitempty"` - InBroadcastPkts *ywrapper.UintValue `protobuf:"bytes,120244022,opt,name=in_broadcast_pkts,json=inBroadcastPkts,proto3" json:"in_broadcast_pkts,omitempty"` - InDiscards *ywrapper.UintValue `protobuf:"bytes,307490461,opt,name=in_discards,json=inDiscards,proto3" json:"in_discards,omitempty"` - InErrors *ywrapper.UintValue `protobuf:"bytes,319720873,opt,name=in_errors,json=inErrors,proto3" json:"in_errors,omitempty"` - InFcsErrors *ywrapper.UintValue `protobuf:"bytes,169858424,opt,name=in_fcs_errors,json=inFcsErrors,proto3" json:"in_fcs_errors,omitempty"` - InMulticastPkts *ywrapper.UintValue `protobuf:"bytes,320618859,opt,name=in_multicast_pkts,json=inMulticastPkts,proto3" json:"in_multicast_pkts,omitempty"` - InOctets *ywrapper.UintValue `protobuf:"bytes,530205868,opt,name=in_octets,json=inOctets,proto3" json:"in_octets,omitempty"` - InPkts *ywrapper.UintValue `protobuf:"bytes,441153352,opt,name=in_pkts,json=inPkts,proto3" json:"in_pkts,omitempty"` - InUnicastPkts *ywrapper.UintValue `protobuf:"bytes,177838880,opt,name=in_unicast_pkts,json=inUnicastPkts,proto3" json:"in_unicast_pkts,omitempty"` - InUnknownProtos *ywrapper.UintValue `protobuf:"bytes,146059814,opt,name=in_unknown_protos,json=inUnknownProtos,proto3" json:"in_unknown_protos,omitempty"` - LastClear *ywrapper.UintValue `protobuf:"bytes,518046966,opt,name=last_clear,json=lastClear,proto3" json:"last_clear,omitempty"` - OutBroadcastPkts *ywrapper.UintValue `protobuf:"bytes,501221245,opt,name=out_broadcast_pkts,json=outBroadcastPkts,proto3" json:"out_broadcast_pkts,omitempty"` - OutDiscards *ywrapper.UintValue `protobuf:"bytes,159539762,opt,name=out_discards,json=outDiscards,proto3" json:"out_discards,omitempty"` - OutErrors *ywrapper.UintValue `protobuf:"bytes,466636898,opt,name=out_errors,json=outErrors,proto3" json:"out_errors,omitempty"` - OutMulticastPkts *ywrapper.UintValue `protobuf:"bytes,326155776,opt,name=out_multicast_pkts,json=outMulticastPkts,proto3" json:"out_multicast_pkts,omitempty"` - OutOctets *ywrapper.UintValue `protobuf:"bytes,50579235,opt,name=out_octets,json=outOctets,proto3" json:"out_octets,omitempty"` - OutPkts *ywrapper.UintValue `protobuf:"bytes,29497115,opt,name=out_pkts,json=outPkts,proto3" json:"out_pkts,omitempty"` - OutUnicastPkts *ywrapper.UintValue `protobuf:"bytes,297910971,opt,name=out_unicast_pkts,json=outUnicastPkts,proto3" json:"out_unicast_pkts,omitempty"` -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) Reset() { - *x = Interfaces_Interface_Subinterfaces_Subinterface_State_Counters{} - if protoimpl.UnsafeEnabled { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[14] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) ProtoMessage() {} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) ProtoReflect() protoreflect.Message { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[14] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Interfaces_Interface_Subinterfaces_Subinterface_State_Counters.ProtoReflect.Descriptor instead. -func (*Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) Descriptor() ([]byte, []int) { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescGZIP(), []int{0, 0, 3, 0, 1, 0} -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) GetCarrierTransitions() *ywrapper.UintValue { - if x != nil { - return x.CarrierTransitions - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) GetInBroadcastPkts() *ywrapper.UintValue { - if x != nil { - return x.InBroadcastPkts - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) GetInDiscards() *ywrapper.UintValue { - if x != nil { - return x.InDiscards - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) GetInErrors() *ywrapper.UintValue { - if x != nil { - return x.InErrors - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) GetInFcsErrors() *ywrapper.UintValue { - if x != nil { - return x.InFcsErrors - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) GetInMulticastPkts() *ywrapper.UintValue { - if x != nil { - return x.InMulticastPkts - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) GetInOctets() *ywrapper.UintValue { - if x != nil { - return x.InOctets - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) GetInPkts() *ywrapper.UintValue { - if x != nil { - return x.InPkts - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) GetInUnicastPkts() *ywrapper.UintValue { - if x != nil { - return x.InUnicastPkts - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) GetInUnknownProtos() *ywrapper.UintValue { - if x != nil { - return x.InUnknownProtos - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) GetLastClear() *ywrapper.UintValue { - if x != nil { - return x.LastClear - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) GetOutBroadcastPkts() *ywrapper.UintValue { - if x != nil { - return x.OutBroadcastPkts - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) GetOutDiscards() *ywrapper.UintValue { - if x != nil { - return x.OutDiscards - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) GetOutErrors() *ywrapper.UintValue { - if x != nil { - return x.OutErrors - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) GetOutMulticastPkts() *ywrapper.UintValue { - if x != nil { - return x.OutMulticastPkts - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) GetOutOctets() *ywrapper.UintValue { - if x != nil { - return x.OutOctets - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) GetOutPkts() *ywrapper.UintValue { - if x != nil { - return x.OutPkts - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) GetOutUnicastPkts() *ywrapper.UintValue { - if x != nil { - return x.OutUnicastPkts - } - return nil -} - -var File_openconfig_openconfig_interfaces_openconfig_interfaces_proto protoreflect.FileDescriptor - -var file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDesc = []byte{ - 0x0a, 0x3c, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x6f, 0x70, 0x65, - 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x73, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x20, - 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, - 0x1a, 0x38, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, - 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x79, 0x67, 0x6f, 0x74, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2f, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2f, 0x79, 0x77, 0x72, 0x61, - 0x70, 0x70, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x30, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x2f, 0x79, 0x67, 0x6f, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x79, 0x65, 0x78, - 0x74, 0x2f, 0x79, 0x65, 0x78, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x6f, 0x70, - 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2f, 0x65, - 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf3, 0x5a, 0x0a, 0x0a, 0x49, - 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x12, 0x75, 0x0a, 0x09, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x18, 0xfa, 0xa7, 0xba, 0xc9, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x39, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x6f, 0x70, - 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x49, - 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x42, 0x18, 0x82, 0x41, 0x15, - 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x52, 0x09, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x1a, 0xd3, 0x58, 0x0a, 0x09, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x12, 0x7a, - 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0xeb, 0xb4, 0xac, 0x9f, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, - 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, - 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x42, 0x1f, 0x82, 0x41, 0x1c, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x83, 0x01, 0x0a, 0x09, 0x68, - 0x6f, 0x6c, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0xd4, 0xfd, 0xf1, 0x53, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x3f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x6f, - 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, - 0x61, 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, - 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2e, 0x48, 0x6f, 0x6c, 0x64, 0x54, 0x69, - 0x6d, 0x65, 0x42, 0x22, 0x82, 0x41, 0x1f, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x68, 0x6f, 0x6c, - 0x64, 0x2d, 0x74, 0x69, 0x6d, 0x65, 0x52, 0x08, 0x68, 0x6f, 0x6c, 0x64, 0x54, 0x69, 0x6d, 0x65, - 0x12, 0x76, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0xac, 0xc6, 0xe6, 0xb8, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x3c, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x42, 0x1e, 0x82, 0x41, 0x1b, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x96, 0x01, 0x0a, 0x0d, 0x73, 0x75, 0x62, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x18, 0x95, 0x9b, 0xa7, 0x9c, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x44, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2e, 0x53, 0x75, 0x62, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x42, 0x26, 0x82, 0x41, 0x23, 0x2f, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x73, 0x52, 0x0d, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x73, 0x1a, 0xc9, 0x04, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x68, 0x0a, 0x0b, - 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0xb4, 0xb3, 0xc9, 0xc7, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, - 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x2b, 0x82, 0x41, - 0x28, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x64, 0x65, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x59, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, - 0x64, 0x18, 0xed, 0xfe, 0xdf, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, - 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, - 0x27, 0x82, 0x41, 0x24, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x2f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, - 0x64, 0x12, 0x6a, 0x0a, 0x0d, 0x6c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x6d, 0x6f, - 0x64, 0x65, 0x18, 0xbb, 0xb4, 0xf1, 0x78, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, - 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x42, 0x2d, 0x82, 0x41, 0x2a, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, - 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x2f, 0x6c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, 0x2d, 0x6d, 0x6f, 0x64, 0x65, 0x52, - 0x0c, 0x6c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x4e, 0x0a, - 0x03, 0x6d, 0x74, 0x75, 0x18, 0xa6, 0x87, 0xb2, 0xb3, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, - 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x42, 0x23, 0x82, 0x41, 0x20, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x63, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x6d, 0x74, 0x75, 0x52, 0x03, 0x6d, 0x74, 0x75, 0x12, 0x52, 0x0a, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x9b, 0xf0, 0xd9, 0x18, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, - 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x24, 0x82, 0x41, 0x21, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, - 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x52, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x12, 0x6a, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x9e, 0xbf, 0xf9, 0x44, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x2d, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, - 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x49, 0x45, 0x54, 0x46, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, - 0x61, 0x63, 0x65, 0x73, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x54, 0x79, 0x70, - 0x65, 0x42, 0x24, 0x82, 0x41, 0x21, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x1a, 0x9d, 0x05, - 0x0a, 0x08, 0x48, 0x6f, 0x6c, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x8d, 0x01, 0x0a, 0x06, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0xd9, 0xb3, 0xf6, 0x96, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x46, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x6f, 0x70, 0x65, - 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, - 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2e, 0x48, 0x6f, 0x6c, 0x64, 0x54, 0x69, 0x6d, 0x65, - 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x29, 0x82, 0x41, 0x26, 0x2f, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x2f, 0x68, 0x6f, 0x6c, 0x64, 0x2d, 0x74, 0x69, 0x6d, 0x65, 0x2f, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x89, 0x01, 0x0a, 0x05, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x18, 0xae, 0xd3, 0xa8, 0xe6, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x45, - 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x6f, 0x70, 0x65, 0x6e, - 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2e, 0x48, 0x6f, 0x6c, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x2e, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x42, 0x28, 0x82, 0x41, 0x25, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, - 0x68, 0x6f, 0x6c, 0x64, 0x2d, 0x74, 0x69, 0x6d, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x52, - 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x1a, 0xba, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x12, 0x5a, 0x0a, 0x04, 0x64, 0x6f, 0x77, 0x6e, 0x18, 0xd8, 0x8c, 0xd0, 0x51, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, - 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x2e, 0x82, 0x41, 0x2b, 0x2f, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x2f, 0x68, 0x6f, 0x6c, 0x64, 0x2d, 0x74, 0x69, 0x6d, 0x65, 0x2f, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x2f, 0x64, 0x6f, 0x77, 0x6e, 0x52, 0x04, 0x64, 0x6f, 0x77, 0x6e, 0x12, 0x54, 0x0a, - 0x02, 0x75, 0x70, 0x18, 0xfb, 0xe3, 0xc9, 0x1d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, - 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x42, 0x2c, 0x82, 0x41, 0x29, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x68, 0x6f, 0x6c, 0x64, - 0x2d, 0x74, 0x69, 0x6d, 0x65, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x75, 0x70, 0x52, - 0x02, 0x75, 0x70, 0x1a, 0xb7, 0x01, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x59, 0x0a, - 0x04, 0x64, 0x6f, 0x77, 0x6e, 0x18, 0xe9, 0x86, 0x87, 0x50, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, - 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x42, 0x2d, 0x82, 0x41, 0x2a, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x68, 0x6f, - 0x6c, 0x64, 0x2d, 0x74, 0x69, 0x6d, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x64, 0x6f, - 0x77, 0x6e, 0x52, 0x04, 0x64, 0x6f, 0x77, 0x6e, 0x12, 0x53, 0x0a, 0x02, 0x75, 0x70, 0x18, 0xae, - 0xc9, 0xde, 0x6a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, - 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x2b, 0x82, 0x41, - 0x28, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x68, 0x6f, 0x6c, 0x64, 0x2d, 0x74, 0x69, 0x6d, 0x65, - 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x75, 0x70, 0x52, 0x02, 0x75, 0x70, 0x1a, 0x9b, 0x1e, - 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x9c, 0x01, 0x0a, 0x0c, 0x61, 0x64, 0x6d, 0x69, - 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0xab, 0xee, 0xa0, 0xe2, 0x01, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x48, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, - 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, - 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x2e, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x2b, 0x82, 0x41, - 0x28, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x61, 0x64, 0x6d, - 0x69, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x0b, 0x61, 0x64, 0x6d, 0x69, 0x6e, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x8d, 0x01, 0x0a, 0x08, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x65, 0x72, 0x73, 0x18, 0x8c, 0xac, 0xf1, 0x27, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x45, 0x2e, 0x6f, - 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, - 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, - 0x65, 0x72, 0x73, 0x42, 0x27, 0x82, 0x41, 0x24, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x52, 0x08, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x12, 0x67, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x97, 0x9f, 0xd9, 0xb9, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x15, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, - 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x2a, 0x82, 0x41, 0x27, 0x2f, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x59, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x9e, 0x9b, 0xe6, 0x9d, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, - 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x26, 0x82, 0x41, 0x23, 0x2f, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, - 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, - 0x64, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x58, 0x0a, 0x07, 0x69, 0x66, - 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0xaa, 0xd7, 0xae, 0x37, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, - 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x42, 0x26, 0x82, 0x41, 0x23, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x2f, 0x69, 0x66, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x07, 0x69, 0x66, 0x69, - 0x6e, 0x64, 0x65, 0x78, 0x12, 0x63, 0x0a, 0x0b, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x63, 0x68, 0x61, - 0x6e, 0x67, 0x65, 0x18, 0x90, 0xe1, 0xdc, 0x3c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, - 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x42, 0x2a, 0x82, 0x41, 0x27, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x2f, 0x6c, 0x61, 0x73, 0x74, 0x2d, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x0a, 0x6c, - 0x61, 0x73, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x59, 0x0a, 0x07, 0x6c, 0x6f, 0x67, - 0x69, 0x63, 0x61, 0x6c, 0x18, 0xb8, 0xc7, 0x83, 0xd2, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, - 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x42, 0x26, 0x82, 0x41, 0x23, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x2f, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x52, 0x07, 0x6c, 0x6f, 0x67, - 0x69, 0x63, 0x61, 0x6c, 0x12, 0x6a, 0x0a, 0x0d, 0x6c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, - 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0xd8, 0x96, 0xea, 0xb1, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x42, 0x2c, 0x82, 0x41, 0x29, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, - 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x2f, 0x6c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, 0x2d, 0x6d, 0x6f, - 0x64, 0x65, 0x52, 0x0c, 0x6c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, 0x4d, 0x6f, 0x64, 0x65, - 0x12, 0x4c, 0x0a, 0x03, 0x6d, 0x74, 0x75, 0x18, 0xd5, 0x9a, 0xfb, 0x2d, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x22, 0x82, 0x41, 0x1f, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x6d, 0x74, 0x75, 0x52, 0x03, 0x6d, 0x74, 0x75, 0x12, 0x52, - 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0xee, 0xf4, 0x8a, 0xf0, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x15, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x72, 0x69, - 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x23, 0x82, 0x41, 0x20, 0x2f, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0x98, 0x01, 0x0a, 0x0b, 0x6f, 0x70, 0x65, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x18, 0xf2, 0xca, 0xa6, 0xe0, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x47, 0x2e, 0x6f, - 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, - 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x2a, 0x82, 0x41, 0x27, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x6f, 0x70, 0x65, 0x72, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x52, 0x0a, 0x6f, 0x70, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x6a, 0x0a, - 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0xe3, 0xd3, 0xe3, 0xaa, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x2d, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x65, 0x6e, 0x75, - 0x6d, 0x73, 0x2e, 0x49, 0x45, 0x54, 0x46, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x73, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x42, 0x23, - 0x82, 0x41, 0x20, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x74, - 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x1a, 0xbe, 0x10, 0x0a, 0x08, 0x43, 0x6f, - 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x12, 0x85, 0x01, 0x0a, 0x13, 0x63, 0x61, 0x72, 0x72, 0x69, - 0x65, 0x72, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xba, - 0xc1, 0x90, 0x81, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, - 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x3b, 0x82, - 0x41, 0x38, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x63, 0x61, 0x72, 0x72, 0x69, 0x65, 0x72, 0x2d, 0x74, - 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x12, 0x63, 0x61, 0x72, 0x72, - 0x69, 0x65, 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x7e, - 0x0a, 0x11, 0x69, 0x6e, 0x5f, 0x62, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x5f, 0x70, - 0x6b, 0x74, 0x73, 0x18, 0x85, 0x96, 0xce, 0x85, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, - 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x42, 0x39, 0x82, 0x41, 0x36, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x69, 0x6e, 0x2d, 0x62, - 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x2d, 0x70, 0x6b, 0x74, 0x73, 0x52, 0x0f, 0x69, - 0x6e, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x50, 0x6b, 0x74, 0x73, 0x12, 0x6c, - 0x0a, 0x0b, 0x69, 0x6e, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x73, 0x18, 0xfa, 0x95, - 0xdb, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, - 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x33, 0x82, 0x41, 0x30, - 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x65, 0x72, 0x73, 0x2f, 0x69, 0x6e, 0x2d, 0x64, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x73, - 0x52, 0x0a, 0x69, 0x6e, 0x44, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x73, 0x12, 0x67, 0x0a, 0x09, - 0x69, 0x6e, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0xea, 0xcd, 0xe2, 0xd9, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, - 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x31, 0x82, 0x41, 0x2e, 0x2f, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, - 0x73, 0x2f, 0x69, 0x6e, 0x2d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x52, 0x08, 0x69, 0x6e, 0x45, - 0x72, 0x72, 0x6f, 0x72, 0x73, 0x12, 0x72, 0x0a, 0x0d, 0x69, 0x6e, 0x5f, 0x66, 0x63, 0x73, 0x5f, - 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0xf3, 0xdd, 0x94, 0xef, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x35, 0x82, 0x41, 0x32, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x69, - 0x6e, 0x2d, 0x66, 0x63, 0x73, 0x2d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x52, 0x0b, 0x69, 0x6e, - 0x46, 0x63, 0x73, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x12, 0x7d, 0x0a, 0x11, 0x69, 0x6e, 0x5f, - 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x6b, 0x74, 0x73, 0x18, 0x88, - 0xb3, 0x81, 0x36, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, - 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x39, 0x82, 0x41, - 0x36, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x69, 0x6e, 0x2d, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x61, - 0x73, 0x74, 0x2d, 0x70, 0x6b, 0x74, 0x73, 0x52, 0x0f, 0x69, 0x6e, 0x4d, 0x75, 0x6c, 0x74, 0x69, - 0x63, 0x61, 0x73, 0x74, 0x50, 0x6b, 0x74, 0x73, 0x12, 0x67, 0x0a, 0x09, 0x69, 0x6e, 0x5f, 0x6f, - 0x63, 0x74, 0x65, 0x74, 0x73, 0x18, 0xcb, 0x97, 0xed, 0x9e, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x42, 0x31, 0x82, 0x41, 0x2e, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, - 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x69, 0x6e, - 0x2d, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x73, 0x52, 0x08, 0x69, 0x6e, 0x4f, 0x63, 0x74, 0x65, 0x74, - 0x73, 0x12, 0x61, 0x0a, 0x07, 0x69, 0x6e, 0x5f, 0x70, 0x6b, 0x74, 0x73, 0x18, 0xe3, 0xfb, 0xed, - 0xc4, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, - 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x2f, 0x82, 0x41, 0x2c, - 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x65, 0x72, 0x73, 0x2f, 0x69, 0x6e, 0x2d, 0x70, 0x6b, 0x74, 0x73, 0x52, 0x06, 0x69, 0x6e, - 0x50, 0x6b, 0x74, 0x73, 0x12, 0x78, 0x0a, 0x0f, 0x69, 0x6e, 0x5f, 0x75, 0x6e, 0x69, 0x63, 0x61, - 0x73, 0x74, 0x5f, 0x70, 0x6b, 0x74, 0x73, 0x18, 0xf3, 0xf5, 0x89, 0x82, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, - 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x37, 0x82, 0x41, 0x34, 0x2f, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x2f, - 0x69, 0x6e, 0x2d, 0x75, 0x6e, 0x69, 0x63, 0x61, 0x73, 0x74, 0x2d, 0x70, 0x6b, 0x74, 0x73, 0x52, - 0x0d, 0x69, 0x6e, 0x55, 0x6e, 0x69, 0x63, 0x61, 0x73, 0x74, 0x50, 0x6b, 0x74, 0x73, 0x12, 0x7d, - 0x0a, 0x11, 0x69, 0x6e, 0x5f, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x5f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x73, 0x18, 0xa9, 0xbf, 0x92, 0x73, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, - 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x42, 0x39, 0x82, 0x41, 0x36, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x69, 0x6e, 0x2d, 0x75, 0x6e, - 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x2d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x52, 0x0f, 0x69, 0x6e, - 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x12, 0x69, 0x0a, - 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x18, 0xc7, 0xb9, 0xd9, 0x58, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, - 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x32, 0x82, 0x41, 0x2f, 0x2f, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, - 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, - 0x72, 0x73, 0x2f, 0x6c, 0x61, 0x73, 0x74, 0x2d, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x52, 0x09, 0x6c, - 0x61, 0x73, 0x74, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x12, 0x81, 0x01, 0x0a, 0x12, 0x6f, 0x75, 0x74, - 0x5f, 0x62, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x6b, 0x74, 0x73, 0x18, - 0xe4, 0xef, 0xb9, 0xa1, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, - 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x3a, - 0x82, 0x41, 0x37, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x6f, 0x75, 0x74, 0x2d, 0x62, 0x72, 0x6f, 0x61, - 0x64, 0x63, 0x61, 0x73, 0x74, 0x2d, 0x70, 0x6b, 0x74, 0x73, 0x52, 0x10, 0x6f, 0x75, 0x74, 0x42, - 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x50, 0x6b, 0x74, 0x73, 0x12, 0x6f, 0x0a, 0x0c, - 0x6f, 0x75, 0x74, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x73, 0x18, 0xc7, 0xa5, 0x92, - 0x79, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, - 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x34, 0x82, 0x41, 0x31, 0x2f, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x65, 0x72, 0x73, 0x2f, 0x6f, 0x75, 0x74, 0x2d, 0x64, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x73, - 0x52, 0x0b, 0x6f, 0x75, 0x74, 0x44, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x73, 0x12, 0x6a, 0x0a, - 0x0a, 0x6f, 0x75, 0x74, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0xc7, 0xec, 0xd1, 0xe0, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, - 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x32, 0x82, 0x41, 0x2f, 0x2f, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x65, 0x72, 0x73, 0x2f, 0x6f, 0x75, 0x74, 0x2d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x52, 0x09, - 0x6f, 0x75, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x12, 0x81, 0x01, 0x0a, 0x12, 0x6f, 0x75, - 0x74, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x6b, 0x74, 0x73, - 0x18, 0xf5, 0xb0, 0xa8, 0xda, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, - 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, - 0x3a, 0x82, 0x41, 0x37, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x6f, 0x75, 0x74, 0x2d, 0x6d, 0x75, 0x6c, - 0x74, 0x69, 0x63, 0x61, 0x73, 0x74, 0x2d, 0x70, 0x6b, 0x74, 0x73, 0x52, 0x10, 0x6f, 0x75, 0x74, - 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x61, 0x73, 0x74, 0x50, 0x6b, 0x74, 0x73, 0x12, 0x69, 0x0a, - 0x0a, 0x6f, 0x75, 0x74, 0x5f, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x73, 0x18, 0xca, 0xb3, 0xec, 0x5f, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, - 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x32, 0x82, 0x41, 0x2f, 0x2f, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, - 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, - 0x72, 0x73, 0x2f, 0x6f, 0x75, 0x74, 0x2d, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x73, 0x52, 0x09, 0x6f, - 0x75, 0x74, 0x4f, 0x63, 0x74, 0x65, 0x74, 0x73, 0x12, 0x64, 0x0a, 0x08, 0x6f, 0x75, 0x74, 0x5f, - 0x70, 0x6b, 0x74, 0x73, 0x18, 0x8a, 0xf2, 0xd3, 0xd0, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, - 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x42, 0x30, 0x82, 0x41, 0x2d, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x6f, 0x75, 0x74, - 0x2d, 0x70, 0x6b, 0x74, 0x73, 0x52, 0x07, 0x6f, 0x75, 0x74, 0x50, 0x6b, 0x74, 0x73, 0x12, 0x7a, - 0x0a, 0x10, 0x6f, 0x75, 0x74, 0x5f, 0x75, 0x6e, 0x69, 0x63, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x6b, - 0x74, 0x73, 0x18, 0xa6, 0xae, 0xb6, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, - 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x42, 0x38, 0x82, 0x41, 0x35, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, - 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x6f, 0x75, 0x74, 0x2d, 0x75, 0x6e, - 0x69, 0x63, 0x61, 0x73, 0x74, 0x2d, 0x70, 0x6b, 0x74, 0x73, 0x52, 0x0e, 0x6f, 0x75, 0x74, 0x55, - 0x6e, 0x69, 0x63, 0x61, 0x73, 0x74, 0x50, 0x6b, 0x74, 0x73, 0x22, 0x83, 0x01, 0x0a, 0x0b, 0x41, - 0x64, 0x6d, 0x69, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x15, 0x0a, 0x11, 0x41, 0x44, - 0x4d, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x45, 0x54, 0x10, - 0x00, 0x12, 0x19, 0x0a, 0x0e, 0x41, 0x44, 0x4d, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, - 0x5f, 0x55, 0x50, 0x10, 0x01, 0x1a, 0x05, 0x82, 0x41, 0x02, 0x55, 0x50, 0x12, 0x1d, 0x0a, 0x10, - 0x41, 0x44, 0x4d, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x44, 0x4f, 0x57, 0x4e, - 0x10, 0x02, 0x1a, 0x07, 0x82, 0x41, 0x04, 0x44, 0x4f, 0x57, 0x4e, 0x12, 0x23, 0x0a, 0x13, 0x41, - 0x44, 0x4d, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x54, 0x45, 0x53, 0x54, 0x49, - 0x4e, 0x47, 0x10, 0x03, 0x1a, 0x0a, 0x82, 0x41, 0x07, 0x54, 0x45, 0x53, 0x54, 0x49, 0x4e, 0x47, - 0x22, 0xa8, 0x02, 0x0a, 0x0a, 0x4f, 0x70, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, - 0x14, 0x0a, 0x10, 0x4f, 0x50, 0x45, 0x52, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, - 0x53, 0x45, 0x54, 0x10, 0x00, 0x12, 0x18, 0x0a, 0x0d, 0x4f, 0x50, 0x45, 0x52, 0x53, 0x54, 0x41, - 0x54, 0x55, 0x53, 0x5f, 0x55, 0x50, 0x10, 0x02, 0x1a, 0x05, 0x82, 0x41, 0x02, 0x55, 0x50, 0x12, - 0x1c, 0x0a, 0x0f, 0x4f, 0x50, 0x45, 0x52, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x44, 0x4f, - 0x57, 0x4e, 0x10, 0x03, 0x1a, 0x07, 0x82, 0x41, 0x04, 0x44, 0x4f, 0x57, 0x4e, 0x12, 0x22, 0x0a, - 0x12, 0x4f, 0x50, 0x45, 0x52, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x54, 0x45, 0x53, 0x54, - 0x49, 0x4e, 0x47, 0x10, 0x04, 0x1a, 0x0a, 0x82, 0x41, 0x07, 0x54, 0x45, 0x53, 0x54, 0x49, 0x4e, - 0x47, 0x12, 0x22, 0x0a, 0x12, 0x4f, 0x50, 0x45, 0x52, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, - 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x05, 0x1a, 0x0a, 0x82, 0x41, 0x07, 0x55, 0x4e, - 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x12, 0x22, 0x0a, 0x12, 0x4f, 0x50, 0x45, 0x52, 0x53, 0x54, 0x41, - 0x54, 0x55, 0x53, 0x5f, 0x44, 0x4f, 0x52, 0x4d, 0x41, 0x4e, 0x54, 0x10, 0x06, 0x1a, 0x0a, 0x82, - 0x41, 0x07, 0x44, 0x4f, 0x52, 0x4d, 0x41, 0x4e, 0x54, 0x12, 0x2a, 0x0a, 0x16, 0x4f, 0x50, 0x45, - 0x52, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x50, 0x52, 0x45, 0x53, - 0x45, 0x4e, 0x54, 0x10, 0x07, 0x1a, 0x0e, 0x82, 0x41, 0x0b, 0x4e, 0x4f, 0x54, 0x5f, 0x50, 0x52, - 0x45, 0x53, 0x45, 0x4e, 0x54, 0x12, 0x34, 0x0a, 0x1b, 0x4f, 0x50, 0x45, 0x52, 0x53, 0x54, 0x41, - 0x54, 0x55, 0x53, 0x5f, 0x4c, 0x4f, 0x57, 0x45, 0x52, 0x5f, 0x4c, 0x41, 0x59, 0x45, 0x52, 0x5f, - 0x44, 0x4f, 0x57, 0x4e, 0x10, 0x08, 0x1a, 0x13, 0x82, 0x41, 0x10, 0x4c, 0x4f, 0x57, 0x45, 0x52, - 0x5f, 0x4c, 0x41, 0x59, 0x45, 0x52, 0x5f, 0x44, 0x4f, 0x57, 0x4e, 0x1a, 0xa8, 0x2c, 0x0a, 0x0d, - 0x53, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x12, 0xb1, 0x01, - 0x0a, 0x0c, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x18, 0x83, - 0xa8, 0xd1, 0xdd, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x54, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x2e, 0x53, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x53, - 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x42, 0x33, - 0x82, 0x41, 0x30, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, - 0x61, 0x63, 0x65, 0x52, 0x0c, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x1a, 0x86, 0x29, 0x0a, 0x0c, 0x53, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x12, 0xaf, 0x01, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x84, 0x9f, - 0xb9, 0x53, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x58, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, - 0x61, 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2e, 0x53, - 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x53, 0x75, 0x62, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x42, 0x3a, 0x82, 0x41, 0x37, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, - 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x63, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x12, 0xac, 0x01, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x9d, - 0x89, 0xae, 0xef, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x57, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x2e, 0x53, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x53, - 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x42, 0x39, 0x82, 0x41, 0x36, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x1a, 0xf6, 0x02, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x83, - 0x01, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0xdf, - 0xe7, 0xea, 0x85, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, - 0x70, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, - 0x46, 0x82, 0x41, 0x43, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x64, 0x65, 0x73, 0x63, - 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x75, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, - 0xa6, 0xef, 0xdd, 0x8d, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, - 0x70, 0x70, 0x65, 0x72, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x42, - 0x82, 0x41, 0x3f, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, - 0x61, 0x63, 0x65, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x65, 0x6e, 0x61, 0x62, 0x6c, - 0x65, 0x64, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x6f, 0x0a, 0x05, 0x69, - 0x6e, 0x64, 0x65, 0x78, 0x18, 0x95, 0xa3, 0x95, 0x85, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, - 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x42, 0x40, 0x82, 0x41, 0x3d, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, - 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, - 0x69, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x9b, 0x23, 0x0a, - 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0xd1, 0x01, 0x0a, 0x0c, 0x61, 0x64, 0x6d, 0x69, 0x6e, - 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x88, 0x81, 0xc3, 0x77, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x63, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x6f, 0x70, - 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x49, - 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2e, 0x53, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x53, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, - 0x61, 0x63, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x46, 0x82, 0x41, 0x43, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, - 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, - 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x0b, 0x61, - 0x64, 0x6d, 0x69, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0xc4, 0x01, 0x0a, 0x08, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x18, 0xdf, 0x80, 0xc3, 0xe6, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x60, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x6f, - 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, - 0x61, 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, - 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2e, 0x53, 0x75, 0x62, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x53, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, - 0x65, 0x72, 0x73, 0x42, 0x42, 0x82, 0x41, 0x3f, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, - 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x52, 0x08, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, - 0x73, 0x12, 0x81, 0x01, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0xe6, 0xa7, 0xe8, 0x17, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x79, 0x77, 0x72, - 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x42, 0x45, 0x82, 0x41, 0x42, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x64, 0x65, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x74, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, - 0x18, 0xb3, 0xe8, 0xb3, 0xdf, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, - 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, - 0x41, 0x82, 0x41, 0x3e, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x65, 0x6e, 0x61, 0x62, 0x6c, - 0x65, 0x64, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x74, 0x0a, 0x07, 0x69, - 0x66, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0xe7, 0xa0, 0x91, 0xf4, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x41, 0x82, 0x41, 0x3e, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, - 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, - 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x2f, 0x69, 0x66, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x07, 0x69, 0x66, 0x69, 0x6e, 0x64, 0x65, - 0x78, 0x12, 0x6d, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x9c, 0xaa, 0xc0, 0x26, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, - 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x3f, 0x82, 0x41, 0x3c, 0x2f, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, - 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, - 0x12, 0x7e, 0x0a, 0x0b, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x18, - 0x89, 0x9d, 0xa1, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, - 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x45, 0x82, - 0x41, 0x42, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x6c, 0x61, 0x73, 0x74, 0x2d, 0x63, 0x68, - 0x61, 0x6e, 0x67, 0x65, 0x52, 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, - 0x12, 0x74, 0x0a, 0x07, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x18, 0xf1, 0xf6, 0x9f, 0x8c, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, - 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x41, 0x82, 0x41, 0x3e, 0x2f, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x52, 0x07, 0x6c, - 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x12, 0x6d, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0xf9, - 0xfb, 0x99, 0x85, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, - 0x70, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, - 0x3e, 0x82, 0x41, 0x3b, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x52, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0xce, 0x01, 0x0a, 0x0b, 0x6f, 0x70, 0x65, 0x72, 0x5f, 0x73, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0xdf, 0xa0, 0xd6, 0xbf, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x62, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x6f, 0x70, 0x65, - 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, - 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2e, 0x53, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x53, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x42, 0x45, 0x82, 0x41, 0x42, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, - 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x6f, - 0x70, 0x65, 0x72, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x0a, 0x6f, 0x70, 0x65, 0x72, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x1a, 0xb0, 0x14, 0x0a, 0x08, 0x43, 0x6f, 0x75, 0x6e, 0x74, - 0x65, 0x72, 0x73, 0x12, 0x9f, 0x01, 0x0a, 0x13, 0x63, 0x61, 0x72, 0x72, 0x69, 0x65, 0x72, 0x5f, - 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x95, 0xa6, 0xa5, 0x43, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, - 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x56, 0x82, 0x41, 0x53, 0x2f, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, - 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x63, 0x61, - 0x72, 0x72, 0x69, 0x65, 0x72, 0x2d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x52, 0x12, 0x63, 0x61, 0x72, 0x72, 0x69, 0x65, 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x98, 0x01, 0x0a, 0x11, 0x69, 0x6e, 0x5f, 0x62, 0x72, 0x6f, - 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x6b, 0x74, 0x73, 0x18, 0xb6, 0x8e, 0xab, 0x39, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, - 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x54, 0x82, 0x41, 0x51, 0x2f, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, - 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x69, 0x6e, - 0x2d, 0x62, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x2d, 0x70, 0x6b, 0x74, 0x73, 0x52, - 0x0f, 0x69, 0x6e, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x50, 0x6b, 0x74, 0x73, - 0x12, 0x88, 0x01, 0x0a, 0x0b, 0x69, 0x6e, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x73, - 0x18, 0x9d, 0xdd, 0xcf, 0x92, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, - 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, - 0x4e, 0x82, 0x41, 0x4b, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x65, 0x72, 0x73, 0x2f, 0x69, 0x6e, 0x2d, 0x64, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x73, 0x52, - 0x0a, 0x69, 0x6e, 0x44, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x73, 0x12, 0x82, 0x01, 0x0a, 0x09, - 0x69, 0x6e, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0xa9, 0x9b, 0xba, 0x98, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, - 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x4c, 0x82, 0x41, 0x49, 0x2f, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, - 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x69, 0x6e, 0x2d, - 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x52, 0x08, 0x69, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, - 0x12, 0x8c, 0x01, 0x0a, 0x0d, 0x69, 0x6e, 0x5f, 0x66, 0x63, 0x73, 0x5f, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x73, 0x18, 0xf8, 0xaa, 0xff, 0x50, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, - 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x42, 0x50, 0x82, 0x41, 0x4d, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, - 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x65, 0x72, 0x73, 0x2f, 0x69, 0x6e, 0x2d, 0x66, 0x63, 0x73, 0x2d, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x73, 0x52, 0x0b, 0x69, 0x6e, 0x46, 0x63, 0x73, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x12, - 0x99, 0x01, 0x0a, 0x11, 0x69, 0x6e, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x61, 0x73, 0x74, - 0x5f, 0x70, 0x6b, 0x74, 0x73, 0x18, 0xeb, 0x82, 0xf1, 0x98, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x42, 0x54, 0x82, 0x41, 0x51, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, - 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, - 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x69, 0x6e, 0x2d, 0x6d, 0x75, 0x6c, 0x74, - 0x69, 0x63, 0x61, 0x73, 0x74, 0x2d, 0x70, 0x6b, 0x74, 0x73, 0x52, 0x0f, 0x69, 0x6e, 0x4d, 0x75, - 0x6c, 0x74, 0x69, 0x63, 0x61, 0x73, 0x74, 0x50, 0x6b, 0x74, 0x73, 0x12, 0x82, 0x01, 0x0a, 0x09, - 0x69, 0x6e, 0x5f, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x73, 0x18, 0xac, 0x99, 0xe9, 0xfc, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, - 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x4c, 0x82, 0x41, 0x49, 0x2f, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, - 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x69, 0x6e, 0x2d, - 0x6f, 0x63, 0x74, 0x65, 0x74, 0x73, 0x52, 0x08, 0x69, 0x6e, 0x4f, 0x63, 0x74, 0x65, 0x74, 0x73, - 0x12, 0x7c, 0x0a, 0x07, 0x69, 0x6e, 0x5f, 0x70, 0x6b, 0x74, 0x73, 0x18, 0xc8, 0xee, 0xad, 0xd2, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, - 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x4a, 0x82, 0x41, 0x47, 0x2f, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x69, - 0x6e, 0x2d, 0x70, 0x6b, 0x74, 0x73, 0x52, 0x06, 0x69, 0x6e, 0x50, 0x6b, 0x74, 0x73, 0x12, 0x92, - 0x01, 0x0a, 0x0f, 0x69, 0x6e, 0x5f, 0x75, 0x6e, 0x69, 0x63, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x6b, - 0x74, 0x73, 0x18, 0xa0, 0xb6, 0xe6, 0x54, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, - 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x42, 0x52, 0x82, 0x41, 0x4f, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, - 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x65, 0x72, 0x73, 0x2f, 0x69, 0x6e, 0x2d, 0x75, 0x6e, 0x69, 0x63, 0x61, 0x73, 0x74, 0x2d, - 0x70, 0x6b, 0x74, 0x73, 0x52, 0x0d, 0x69, 0x6e, 0x55, 0x6e, 0x69, 0x63, 0x61, 0x73, 0x74, 0x50, - 0x6b, 0x74, 0x73, 0x12, 0x98, 0x01, 0x0a, 0x11, 0x69, 0x6e, 0x5f, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, - 0x77, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x18, 0xa6, 0xe4, 0xd2, 0x45, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, - 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x54, 0x82, 0x41, 0x51, 0x2f, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, - 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x69, 0x6e, 0x2d, 0x75, - 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x2d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x52, 0x0f, 0x69, - 0x6e, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x12, 0x85, - 0x01, 0x0a, 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x18, 0xf6, 0x89, - 0x83, 0xf7, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, - 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x4d, 0x82, 0x41, - 0x4a, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, - 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, - 0x2f, 0x6c, 0x61, 0x73, 0x74, 0x2d, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x52, 0x09, 0x6c, 0x61, 0x73, - 0x74, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x12, 0x9c, 0x01, 0x0a, 0x12, 0x6f, 0x75, 0x74, 0x5f, 0x62, - 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x6b, 0x74, 0x73, 0x18, 0xfd, 0x8e, - 0x80, 0xef, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, - 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x55, 0x82, 0x41, - 0x52, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, - 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, - 0x2f, 0x6f, 0x75, 0x74, 0x2d, 0x62, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x2d, 0x70, - 0x6b, 0x74, 0x73, 0x52, 0x10, 0x6f, 0x75, 0x74, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, - 0x74, 0x50, 0x6b, 0x74, 0x73, 0x12, 0x8a, 0x01, 0x0a, 0x0c, 0x6f, 0x75, 0x74, 0x5f, 0x64, 0x69, - 0x73, 0x63, 0x61, 0x72, 0x64, 0x73, 0x18, 0xb2, 0xc4, 0x89, 0x4c, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x42, 0x4f, 0x82, 0x41, 0x4c, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, - 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, - 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x6f, 0x75, 0x74, 0x2d, 0x64, 0x69, 0x73, - 0x63, 0x61, 0x72, 0x64, 0x73, 0x52, 0x0b, 0x6f, 0x75, 0x74, 0x44, 0x69, 0x73, 0x63, 0x61, 0x72, - 0x64, 0x73, 0x12, 0x85, 0x01, 0x0a, 0x0a, 0x6f, 0x75, 0x74, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x73, 0x18, 0xe2, 0xa0, 0xc1, 0xde, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, - 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x42, 0x4d, 0x82, 0x41, 0x4a, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, - 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x65, 0x72, 0x73, 0x2f, 0x6f, 0x75, 0x74, 0x2d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x52, - 0x09, 0x6f, 0x75, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x12, 0x9c, 0x01, 0x0a, 0x12, 0x6f, - 0x75, 0x74, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x6b, 0x74, - 0x73, 0x18, 0x80, 0xfc, 0xc2, 0x9b, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, - 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x42, 0x55, 0x82, 0x41, 0x52, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, - 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x65, 0x72, 0x73, 0x2f, 0x6f, 0x75, 0x74, 0x2d, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x61, - 0x73, 0x74, 0x2d, 0x70, 0x6b, 0x74, 0x73, 0x52, 0x10, 0x6f, 0x75, 0x74, 0x4d, 0x75, 0x6c, 0x74, - 0x69, 0x63, 0x61, 0x73, 0x74, 0x50, 0x6b, 0x74, 0x73, 0x12, 0x84, 0x01, 0x0a, 0x0a, 0x6f, 0x75, - 0x74, 0x5f, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x73, 0x18, 0xa3, 0x8e, 0x8f, 0x18, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, - 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x4d, 0x82, 0x41, 0x4a, 0x2f, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, - 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x6f, 0x75, 0x74, 0x2d, 0x6f, - 0x63, 0x74, 0x65, 0x74, 0x73, 0x52, 0x09, 0x6f, 0x75, 0x74, 0x4f, 0x63, 0x74, 0x65, 0x74, 0x73, - 0x12, 0x7e, 0x0a, 0x08, 0x6f, 0x75, 0x74, 0x5f, 0x70, 0x6b, 0x74, 0x73, 0x18, 0x9b, 0xae, 0x88, - 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, - 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x4b, 0x82, 0x41, 0x48, 0x2f, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x6f, - 0x75, 0x74, 0x2d, 0x70, 0x6b, 0x74, 0x73, 0x52, 0x07, 0x6f, 0x75, 0x74, 0x50, 0x6b, 0x74, 0x73, - 0x12, 0x96, 0x01, 0x0a, 0x10, 0x6f, 0x75, 0x74, 0x5f, 0x75, 0x6e, 0x69, 0x63, 0x61, 0x73, 0x74, - 0x5f, 0x70, 0x6b, 0x74, 0x73, 0x18, 0xbb, 0x85, 0x87, 0x8e, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x42, 0x53, 0x82, 0x41, 0x50, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, - 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, - 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x6f, 0x75, 0x74, 0x2d, 0x75, 0x6e, 0x69, - 0x63, 0x61, 0x73, 0x74, 0x2d, 0x70, 0x6b, 0x74, 0x73, 0x52, 0x0e, 0x6f, 0x75, 0x74, 0x55, 0x6e, - 0x69, 0x63, 0x61, 0x73, 0x74, 0x50, 0x6b, 0x74, 0x73, 0x22, 0x83, 0x01, 0x0a, 0x0b, 0x41, 0x64, - 0x6d, 0x69, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x15, 0x0a, 0x11, 0x41, 0x44, 0x4d, - 0x49, 0x4e, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x45, 0x54, 0x10, 0x00, - 0x12, 0x19, 0x0a, 0x0e, 0x41, 0x44, 0x4d, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, - 0x55, 0x50, 0x10, 0x01, 0x1a, 0x05, 0x82, 0x41, 0x02, 0x55, 0x50, 0x12, 0x1d, 0x0a, 0x10, 0x41, - 0x44, 0x4d, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x44, 0x4f, 0x57, 0x4e, 0x10, - 0x02, 0x1a, 0x07, 0x82, 0x41, 0x04, 0x44, 0x4f, 0x57, 0x4e, 0x12, 0x23, 0x0a, 0x13, 0x41, 0x44, - 0x4d, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x54, 0x45, 0x53, 0x54, 0x49, 0x4e, - 0x47, 0x10, 0x03, 0x1a, 0x0a, 0x82, 0x41, 0x07, 0x54, 0x45, 0x53, 0x54, 0x49, 0x4e, 0x47, 0x22, - 0xa8, 0x02, 0x0a, 0x0a, 0x4f, 0x70, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x14, - 0x0a, 0x10, 0x4f, 0x50, 0x45, 0x52, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, - 0x45, 0x54, 0x10, 0x00, 0x12, 0x18, 0x0a, 0x0d, 0x4f, 0x50, 0x45, 0x52, 0x53, 0x54, 0x41, 0x54, - 0x55, 0x53, 0x5f, 0x55, 0x50, 0x10, 0x02, 0x1a, 0x05, 0x82, 0x41, 0x02, 0x55, 0x50, 0x12, 0x1c, - 0x0a, 0x0f, 0x4f, 0x50, 0x45, 0x52, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x44, 0x4f, 0x57, - 0x4e, 0x10, 0x03, 0x1a, 0x07, 0x82, 0x41, 0x04, 0x44, 0x4f, 0x57, 0x4e, 0x12, 0x22, 0x0a, 0x12, - 0x4f, 0x50, 0x45, 0x52, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x54, 0x45, 0x53, 0x54, 0x49, - 0x4e, 0x47, 0x10, 0x04, 0x1a, 0x0a, 0x82, 0x41, 0x07, 0x54, 0x45, 0x53, 0x54, 0x49, 0x4e, 0x47, - 0x12, 0x22, 0x0a, 0x12, 0x4f, 0x50, 0x45, 0x52, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, - 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x05, 0x1a, 0x0a, 0x82, 0x41, 0x07, 0x55, 0x4e, 0x4b, - 0x4e, 0x4f, 0x57, 0x4e, 0x12, 0x22, 0x0a, 0x12, 0x4f, 0x50, 0x45, 0x52, 0x53, 0x54, 0x41, 0x54, - 0x55, 0x53, 0x5f, 0x44, 0x4f, 0x52, 0x4d, 0x41, 0x4e, 0x54, 0x10, 0x06, 0x1a, 0x0a, 0x82, 0x41, - 0x07, 0x44, 0x4f, 0x52, 0x4d, 0x41, 0x4e, 0x54, 0x12, 0x2a, 0x0a, 0x16, 0x4f, 0x50, 0x45, 0x52, - 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x50, 0x52, 0x45, 0x53, 0x45, - 0x4e, 0x54, 0x10, 0x07, 0x1a, 0x0e, 0x82, 0x41, 0x0b, 0x4e, 0x4f, 0x54, 0x5f, 0x50, 0x52, 0x45, - 0x53, 0x45, 0x4e, 0x54, 0x12, 0x34, 0x0a, 0x1b, 0x4f, 0x50, 0x45, 0x52, 0x53, 0x54, 0x41, 0x54, - 0x55, 0x53, 0x5f, 0x4c, 0x4f, 0x57, 0x45, 0x52, 0x5f, 0x4c, 0x41, 0x59, 0x45, 0x52, 0x5f, 0x44, - 0x4f, 0x57, 0x4e, 0x10, 0x08, 0x1a, 0x13, 0x82, 0x41, 0x10, 0x4c, 0x4f, 0x57, 0x45, 0x52, 0x5f, - 0x4c, 0x41, 0x59, 0x45, 0x52, 0x5f, 0x44, 0x4f, 0x57, 0x4e, 0x1a, 0xd9, 0x01, 0x0a, 0x0f, 0x53, - 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x4f, - 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x42, 0x39, 0x82, - 0x41, 0x36, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, - 0x75, 0x0a, 0x0c, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x51, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2e, 0x53, 0x75, - 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x53, 0x75, 0x62, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x52, 0x0c, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x1a, 0x97, 0x01, 0x0a, 0x0c, 0x49, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x31, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x1d, 0x82, 0x41, 0x1a, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, - 0x6e, 0x61, 0x6d, 0x65, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x54, 0x0a, 0x09, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x36, 0x2e, - 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, - 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x52, 0x09, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x42, 0x20, 0x5a, 0x1e, 0x67, 0x69, 0x74, 0x6c, 0x61, 0x62, 0x2e, 0x66, 0x62, 0x69, 0x2e, 0x68, - 0x2d, 0x64, 0x61, 0x2e, 0x64, 0x65, 0x2f, 0x63, 0x6f, 0x63, 0x73, 0x6e, 0x2f, 0x67, 0x6f, 0x73, - 0x64, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescOnce sync.Once - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescData = file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDesc -) - -func file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescGZIP() []byte { - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescOnce.Do(func() { - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescData = protoimpl.X.CompressGZIP(file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescData) - }) - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescData -} - -var file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_enumTypes = make([]protoimpl.EnumInfo, 4) -var file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes = make([]protoimpl.MessageInfo, 15) -var file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_goTypes = []interface{}{ - (Interfaces_Interface_State_AdminStatus)(0), // 0: openconfig.openconfig_interfaces.Interfaces.Interface.State.AdminStatus - (Interfaces_Interface_State_OperStatus)(0), // 1: openconfig.openconfig_interfaces.Interfaces.Interface.State.OperStatus - (Interfaces_Interface_Subinterfaces_Subinterface_State_AdminStatus)(0), // 2: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.AdminStatus - (Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus)(0), // 3: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.OperStatus - (*Interfaces)(nil), // 4: openconfig.openconfig_interfaces.Interfaces - (*Interfaces_Interface)(nil), // 5: openconfig.openconfig_interfaces.Interfaces.Interface - (*Interfaces_InterfaceKey)(nil), // 6: openconfig.openconfig_interfaces.Interfaces.InterfaceKey - (*Interfaces_Interface_Config)(nil), // 7: openconfig.openconfig_interfaces.Interfaces.Interface.Config - (*Interfaces_Interface_HoldTime)(nil), // 8: openconfig.openconfig_interfaces.Interfaces.Interface.HoldTime - (*Interfaces_Interface_State)(nil), // 9: openconfig.openconfig_interfaces.Interfaces.Interface.State - (*Interfaces_Interface_Subinterfaces)(nil), // 10: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces - (*Interfaces_Interface_HoldTime_Config)(nil), // 11: openconfig.openconfig_interfaces.Interfaces.Interface.HoldTime.Config - (*Interfaces_Interface_HoldTime_State)(nil), // 12: openconfig.openconfig_interfaces.Interfaces.Interface.HoldTime.State - (*Interfaces_Interface_State_Counters)(nil), // 13: openconfig.openconfig_interfaces.Interfaces.Interface.State.Counters - (*Interfaces_Interface_Subinterfaces_Subinterface)(nil), // 14: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface - (*Interfaces_Interface_Subinterfaces_SubinterfaceKey)(nil), // 15: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.SubinterfaceKey - (*Interfaces_Interface_Subinterfaces_Subinterface_Config)(nil), // 16: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.Config - (*Interfaces_Interface_Subinterfaces_Subinterface_State)(nil), // 17: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State - (*Interfaces_Interface_Subinterfaces_Subinterface_State_Counters)(nil), // 18: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.Counters - (*ywrapper.StringValue)(nil), // 19: ywrapper.StringValue - (*ywrapper.BoolValue)(nil), // 20: ywrapper.BoolValue - (*ywrapper.UintValue)(nil), // 21: ywrapper.UintValue - (IETFInterfacesInterfaceType)(0), // 22: openconfig.enums.IETFInterfacesInterfaceType -} -var file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_depIdxs = []int32{ - 6, // 0: openconfig.openconfig_interfaces.Interfaces.interface:type_name -> openconfig.openconfig_interfaces.Interfaces.InterfaceKey - 7, // 1: openconfig.openconfig_interfaces.Interfaces.Interface.config:type_name -> openconfig.openconfig_interfaces.Interfaces.Interface.Config - 8, // 2: openconfig.openconfig_interfaces.Interfaces.Interface.hold_time:type_name -> openconfig.openconfig_interfaces.Interfaces.Interface.HoldTime - 9, // 3: openconfig.openconfig_interfaces.Interfaces.Interface.state:type_name -> openconfig.openconfig_interfaces.Interfaces.Interface.State - 10, // 4: openconfig.openconfig_interfaces.Interfaces.Interface.subinterfaces:type_name -> openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces - 5, // 5: openconfig.openconfig_interfaces.Interfaces.InterfaceKey.interface:type_name -> openconfig.openconfig_interfaces.Interfaces.Interface - 19, // 6: openconfig.openconfig_interfaces.Interfaces.Interface.Config.description:type_name -> ywrapper.StringValue - 20, // 7: openconfig.openconfig_interfaces.Interfaces.Interface.Config.enabled:type_name -> ywrapper.BoolValue - 20, // 8: openconfig.openconfig_interfaces.Interfaces.Interface.Config.loopback_mode:type_name -> ywrapper.BoolValue - 21, // 9: openconfig.openconfig_interfaces.Interfaces.Interface.Config.mtu:type_name -> ywrapper.UintValue - 19, // 10: openconfig.openconfig_interfaces.Interfaces.Interface.Config.name:type_name -> ywrapper.StringValue - 22, // 11: openconfig.openconfig_interfaces.Interfaces.Interface.Config.type:type_name -> openconfig.enums.IETFInterfacesInterfaceType - 11, // 12: openconfig.openconfig_interfaces.Interfaces.Interface.HoldTime.config:type_name -> openconfig.openconfig_interfaces.Interfaces.Interface.HoldTime.Config - 12, // 13: openconfig.openconfig_interfaces.Interfaces.Interface.HoldTime.state:type_name -> openconfig.openconfig_interfaces.Interfaces.Interface.HoldTime.State - 0, // 14: openconfig.openconfig_interfaces.Interfaces.Interface.State.admin_status:type_name -> openconfig.openconfig_interfaces.Interfaces.Interface.State.AdminStatus - 13, // 15: openconfig.openconfig_interfaces.Interfaces.Interface.State.counters:type_name -> openconfig.openconfig_interfaces.Interfaces.Interface.State.Counters - 19, // 16: openconfig.openconfig_interfaces.Interfaces.Interface.State.description:type_name -> ywrapper.StringValue - 20, // 17: openconfig.openconfig_interfaces.Interfaces.Interface.State.enabled:type_name -> ywrapper.BoolValue - 21, // 18: openconfig.openconfig_interfaces.Interfaces.Interface.State.ifindex:type_name -> ywrapper.UintValue - 21, // 19: openconfig.openconfig_interfaces.Interfaces.Interface.State.last_change:type_name -> ywrapper.UintValue - 20, // 20: openconfig.openconfig_interfaces.Interfaces.Interface.State.logical:type_name -> ywrapper.BoolValue - 20, // 21: openconfig.openconfig_interfaces.Interfaces.Interface.State.loopback_mode:type_name -> ywrapper.BoolValue - 21, // 22: openconfig.openconfig_interfaces.Interfaces.Interface.State.mtu:type_name -> ywrapper.UintValue - 19, // 23: openconfig.openconfig_interfaces.Interfaces.Interface.State.name:type_name -> ywrapper.StringValue - 1, // 24: openconfig.openconfig_interfaces.Interfaces.Interface.State.oper_status:type_name -> openconfig.openconfig_interfaces.Interfaces.Interface.State.OperStatus - 22, // 25: openconfig.openconfig_interfaces.Interfaces.Interface.State.type:type_name -> openconfig.enums.IETFInterfacesInterfaceType - 15, // 26: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.subinterface:type_name -> openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.SubinterfaceKey - 21, // 27: openconfig.openconfig_interfaces.Interfaces.Interface.HoldTime.Config.down:type_name -> ywrapper.UintValue - 21, // 28: openconfig.openconfig_interfaces.Interfaces.Interface.HoldTime.Config.up:type_name -> ywrapper.UintValue - 21, // 29: openconfig.openconfig_interfaces.Interfaces.Interface.HoldTime.State.down:type_name -> ywrapper.UintValue - 21, // 30: openconfig.openconfig_interfaces.Interfaces.Interface.HoldTime.State.up:type_name -> ywrapper.UintValue - 21, // 31: openconfig.openconfig_interfaces.Interfaces.Interface.State.Counters.carrier_transitions:type_name -> ywrapper.UintValue - 21, // 32: openconfig.openconfig_interfaces.Interfaces.Interface.State.Counters.in_broadcast_pkts:type_name -> ywrapper.UintValue - 21, // 33: openconfig.openconfig_interfaces.Interfaces.Interface.State.Counters.in_discards:type_name -> ywrapper.UintValue - 21, // 34: openconfig.openconfig_interfaces.Interfaces.Interface.State.Counters.in_errors:type_name -> ywrapper.UintValue - 21, // 35: openconfig.openconfig_interfaces.Interfaces.Interface.State.Counters.in_fcs_errors:type_name -> ywrapper.UintValue - 21, // 36: openconfig.openconfig_interfaces.Interfaces.Interface.State.Counters.in_multicast_pkts:type_name -> ywrapper.UintValue - 21, // 37: openconfig.openconfig_interfaces.Interfaces.Interface.State.Counters.in_octets:type_name -> ywrapper.UintValue - 21, // 38: openconfig.openconfig_interfaces.Interfaces.Interface.State.Counters.in_pkts:type_name -> ywrapper.UintValue - 21, // 39: openconfig.openconfig_interfaces.Interfaces.Interface.State.Counters.in_unicast_pkts:type_name -> ywrapper.UintValue - 21, // 40: openconfig.openconfig_interfaces.Interfaces.Interface.State.Counters.in_unknown_protos:type_name -> ywrapper.UintValue - 21, // 41: openconfig.openconfig_interfaces.Interfaces.Interface.State.Counters.last_clear:type_name -> ywrapper.UintValue - 21, // 42: openconfig.openconfig_interfaces.Interfaces.Interface.State.Counters.out_broadcast_pkts:type_name -> ywrapper.UintValue - 21, // 43: openconfig.openconfig_interfaces.Interfaces.Interface.State.Counters.out_discards:type_name -> ywrapper.UintValue - 21, // 44: openconfig.openconfig_interfaces.Interfaces.Interface.State.Counters.out_errors:type_name -> ywrapper.UintValue - 21, // 45: openconfig.openconfig_interfaces.Interfaces.Interface.State.Counters.out_multicast_pkts:type_name -> ywrapper.UintValue - 21, // 46: openconfig.openconfig_interfaces.Interfaces.Interface.State.Counters.out_octets:type_name -> ywrapper.UintValue - 21, // 47: openconfig.openconfig_interfaces.Interfaces.Interface.State.Counters.out_pkts:type_name -> ywrapper.UintValue - 21, // 48: openconfig.openconfig_interfaces.Interfaces.Interface.State.Counters.out_unicast_pkts:type_name -> ywrapper.UintValue - 16, // 49: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.config:type_name -> openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.Config - 17, // 50: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.state:type_name -> openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State - 14, // 51: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.SubinterfaceKey.subinterface:type_name -> openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface - 19, // 52: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.Config.description:type_name -> ywrapper.StringValue - 20, // 53: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.Config.enabled:type_name -> ywrapper.BoolValue - 21, // 54: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.Config.index:type_name -> ywrapper.UintValue - 2, // 55: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.admin_status:type_name -> openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.AdminStatus - 18, // 56: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.counters:type_name -> openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.Counters - 19, // 57: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.description:type_name -> ywrapper.StringValue - 20, // 58: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.enabled:type_name -> ywrapper.BoolValue - 21, // 59: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.ifindex:type_name -> ywrapper.UintValue - 21, // 60: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.index:type_name -> ywrapper.UintValue - 21, // 61: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.last_change:type_name -> ywrapper.UintValue - 20, // 62: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.logical:type_name -> ywrapper.BoolValue - 19, // 63: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.name:type_name -> ywrapper.StringValue - 3, // 64: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.oper_status:type_name -> openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.OperStatus - 21, // 65: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.Counters.carrier_transitions:type_name -> ywrapper.UintValue - 21, // 66: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.Counters.in_broadcast_pkts:type_name -> ywrapper.UintValue - 21, // 67: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.Counters.in_discards:type_name -> ywrapper.UintValue - 21, // 68: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.Counters.in_errors:type_name -> ywrapper.UintValue - 21, // 69: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.Counters.in_fcs_errors:type_name -> ywrapper.UintValue - 21, // 70: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.Counters.in_multicast_pkts:type_name -> ywrapper.UintValue - 21, // 71: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.Counters.in_octets:type_name -> ywrapper.UintValue - 21, // 72: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.Counters.in_pkts:type_name -> ywrapper.UintValue - 21, // 73: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.Counters.in_unicast_pkts:type_name -> ywrapper.UintValue - 21, // 74: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.Counters.in_unknown_protos:type_name -> ywrapper.UintValue - 21, // 75: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.Counters.last_clear:type_name -> ywrapper.UintValue - 21, // 76: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.Counters.out_broadcast_pkts:type_name -> ywrapper.UintValue - 21, // 77: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.Counters.out_discards:type_name -> ywrapper.UintValue - 21, // 78: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.Counters.out_errors:type_name -> ywrapper.UintValue - 21, // 79: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.Counters.out_multicast_pkts:type_name -> ywrapper.UintValue - 21, // 80: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.Counters.out_octets:type_name -> ywrapper.UintValue - 21, // 81: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.Counters.out_pkts:type_name -> ywrapper.UintValue - 21, // 82: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.Counters.out_unicast_pkts:type_name -> ywrapper.UintValue - 83, // [83:83] is the sub-list for method output_type - 83, // [83:83] is the sub-list for method input_type - 83, // [83:83] is the sub-list for extension type_name - 83, // [83:83] is the sub-list for extension extendee - 0, // [0:83] is the sub-list for field type_name -} - -func init() { file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_init() } -func file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_init() { - if File_openconfig_openconfig_interfaces_openconfig_interfaces_proto != nil { - return - } - file_openconfig_enums_enums_proto_init() - if !protoimpl.UnsafeEnabled { - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Interfaces); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Interfaces_Interface); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Interfaces_InterfaceKey); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Interfaces_Interface_Config); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Interfaces_Interface_HoldTime); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Interfaces_Interface_State); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Interfaces_Interface_Subinterfaces); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Interfaces_Interface_HoldTime_Config); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Interfaces_Interface_HoldTime_State); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Interfaces_Interface_State_Counters); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Interfaces_Interface_Subinterfaces_Subinterface); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Interfaces_Interface_Subinterfaces_SubinterfaceKey); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Interfaces_Interface_Subinterfaces_Subinterface_Config); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Interfaces_Interface_Subinterfaces_Subinterface_State); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Interfaces_Interface_Subinterfaces_Subinterface_State_Counters); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDesc, - NumEnums: 4, - NumMessages: 15, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_goTypes, - DependencyIndexes: file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_depIdxs, - EnumInfos: file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_enumTypes, - MessageInfos: file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes, - }.Build() - File_openconfig_openconfig_interfaces_openconfig_interfaces_proto = out.File - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDesc = nil - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_goTypes = nil - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_depIdxs = nil -} diff --git a/api/proto/openconfig/enums/enums.pb.go b/api/proto/openconfig/enums/enums.pb.go deleted file mode 100644 index 3ebe5d22cb235af6c9be0a89d56ccb33c9604f4c..0000000000000000000000000000000000000000 --- a/api/proto/openconfig/enums/enums.pb.go +++ /dev/null @@ -1,149 +0,0 @@ -// openconfig.enums is generated by proto_generator as a protobuf -// representation of a YANG schema. -// -// Input schema modules: -// - ../yang-models/models/openconfig/release/models/interfaces/openconfig-interfaces.yang -// Include paths: -// - ../yang-models/models/... - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.25.0-devel -// protoc v3.13.0 -// source: openconfig/enums/enums.proto - -package openconfig_enums - -import ( - proto "github.com/golang/protobuf/proto" - _ "github.com/openconfig/ygot/proto/yext" - _ "github.com/openconfig/ygot/proto/ywrapper" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// This is a compile-time assertion that a sufficiently up-to-date version -// of the legacy proto package is being used. -const _ = proto.ProtoPackageIsVersion4 - -// IETFInterfacesInterfaceType represents an enumerated type generated for the YANG identity interface-type. -type IETFInterfacesInterfaceType int32 - -const ( - IETFInterfacesInterfaceType_IETFINTERFACESINTERFACETYPE_UNSET IETFInterfacesInterfaceType = 0 -) - -// Enum value maps for IETFInterfacesInterfaceType. -var ( - IETFInterfacesInterfaceType_name = map[int32]string{ - 0: "IETFINTERFACESINTERFACETYPE_UNSET", - } - IETFInterfacesInterfaceType_value = map[string]int32{ - "IETFINTERFACESINTERFACETYPE_UNSET": 0, - } -) - -func (x IETFInterfacesInterfaceType) Enum() *IETFInterfacesInterfaceType { - p := new(IETFInterfacesInterfaceType) - *p = x - return p -} - -func (x IETFInterfacesInterfaceType) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (IETFInterfacesInterfaceType) Descriptor() protoreflect.EnumDescriptor { - return file_openconfig_enums_enums_proto_enumTypes[0].Descriptor() -} - -func (IETFInterfacesInterfaceType) Type() protoreflect.EnumType { - return &file_openconfig_enums_enums_proto_enumTypes[0] -} - -func (x IETFInterfacesInterfaceType) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use IETFInterfacesInterfaceType.Descriptor instead. -func (IETFInterfacesInterfaceType) EnumDescriptor() ([]byte, []int) { - return file_openconfig_enums_enums_proto_rawDescGZIP(), []int{0} -} - -var File_openconfig_enums_enums_proto protoreflect.FileDescriptor - -var file_openconfig_enums_enums_proto_rawDesc = []byte{ - 0x0a, 0x1c, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x65, 0x6e, 0x75, - 0x6d, 0x73, 0x2f, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x10, - 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, - 0x1a, 0x38, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, - 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x79, 0x67, 0x6f, 0x74, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2f, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2f, 0x79, 0x77, 0x72, 0x61, - 0x70, 0x70, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x30, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x2f, 0x79, 0x67, 0x6f, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x79, 0x65, 0x78, - 0x74, 0x2f, 0x79, 0x65, 0x78, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2a, 0x44, 0x0a, 0x1b, - 0x49, 0x45, 0x54, 0x46, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x49, 0x6e, - 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x25, 0x0a, 0x21, 0x49, - 0x45, 0x54, 0x46, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x46, 0x41, 0x43, 0x45, 0x53, 0x49, 0x4e, 0x54, - 0x45, 0x52, 0x46, 0x41, 0x43, 0x45, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x45, 0x54, - 0x10, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_openconfig_enums_enums_proto_rawDescOnce sync.Once - file_openconfig_enums_enums_proto_rawDescData = file_openconfig_enums_enums_proto_rawDesc -) - -func file_openconfig_enums_enums_proto_rawDescGZIP() []byte { - file_openconfig_enums_enums_proto_rawDescOnce.Do(func() { - file_openconfig_enums_enums_proto_rawDescData = protoimpl.X.CompressGZIP(file_openconfig_enums_enums_proto_rawDescData) - }) - return file_openconfig_enums_enums_proto_rawDescData -} - -var file_openconfig_enums_enums_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_openconfig_enums_enums_proto_goTypes = []interface{}{ - (IETFInterfacesInterfaceType)(0), // 0: openconfig.enums.IETFInterfacesInterfaceType -} -var file_openconfig_enums_enums_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_openconfig_enums_enums_proto_init() } -func file_openconfig_enums_enums_proto_init() { - if File_openconfig_enums_enums_proto != nil { - return - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_openconfig_enums_enums_proto_rawDesc, - NumEnums: 1, - NumMessages: 0, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_openconfig_enums_enums_proto_goTypes, - DependencyIndexes: file_openconfig_enums_enums_proto_depIdxs, - EnumInfos: file_openconfig_enums_enums_proto_enumTypes, - }.Build() - File_openconfig_enums_enums_proto = out.File - file_openconfig_enums_enums_proto_rawDesc = nil - file_openconfig_enums_enums_proto_goTypes = nil - file_openconfig_enums_enums_proto_depIdxs = nil -} diff --git a/api/proto/openconfig/enums/enums.proto b/api/proto/openconfig/enums/enums.proto deleted file mode 100644 index 9e536252c00769cef506fdd5a9278d66403a00fd..0000000000000000000000000000000000000000 --- a/api/proto/openconfig/enums/enums.proto +++ /dev/null @@ -1,19 +0,0 @@ -// openconfig.enums is generated by proto_generator as a protobuf -// representation of a YANG schema. -// -// Input schema modules: -// - ../yang-models/models/openconfig/release/models/interfaces/openconfig-interfaces.yang -// Include paths: -// - ../yang-models/models/... -syntax = "proto3"; - -package openconfig.enums; -option go_package = "code.fbi.h-da.de/cocsn/gosdn"; - -import "github.com/openconfig/ygot/proto/ywrapper/ywrapper.proto"; -import "github.com/openconfig/ygot/proto/yext/yext.proto"; - -// IETFInterfacesInterfaceType represents an enumerated type generated for the YANG identity interface-type. -enum IETFInterfacesInterfaceType { - IETFINTERFACESINTERFACETYPE_UNSET = 0; -} diff --git a/api/proto/openconfig/openconfig.pb.go b/api/proto/openconfig/openconfig.pb.go deleted file mode 100644 index e52dc21419f2a632f463b6d7af4dbc430d89235c..0000000000000000000000000000000000000000 --- a/api/proto/openconfig/openconfig.pb.go +++ /dev/null @@ -1,175 +0,0 @@ -// openconfig is generated by proto_generator as a protobuf -// representation of a YANG schema. -// -// Input schema modules: -// - ../yang-models/models/openconfig/release/models/interfaces/openconfig-interfaces.yang -// Include paths: -// - ../yang-models/models/... - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.25.0-devel -// protoc v3.13.0 -// source: openconfig/openconfig.proto - -package openconfig - -import ( - openconfig_interfaces "code.fbi.h-da.de/cocsn/gosdn/api/proto/openconfig/openconfig_interfaces" - proto "github.com/golang/protobuf/proto" - _ "github.com/openconfig/ygot/proto/yext" - _ "github.com/openconfig/ygot/proto/ywrapper" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// This is a compile-time assertion that a sufficiently up-to-date version -// of the legacy proto package is being used. -const _ = proto.ProtoPackageIsVersion4 - -type Device struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Interfaces *openconfig_interfaces.Interfaces `protobuf:"bytes,85031486,opt,name=interfaces,proto3" json:"interfaces,omitempty"` -} - -func (x *Device) Reset() { - *x = Device{} - if protoimpl.UnsafeEnabled { - mi := &file_openconfig_openconfig_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Device) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Device) ProtoMessage() {} - -func (x *Device) ProtoReflect() protoreflect.Message { - mi := &file_openconfig_openconfig_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Device.ProtoReflect.Descriptor instead. -func (*Device) Descriptor() ([]byte, []int) { - return file_openconfig_openconfig_proto_rawDescGZIP(), []int{0} -} - -func (x *Device) GetInterfaces() *openconfig_interfaces.Interfaces { - if x != nil { - return x.Interfaces - } - return nil -} - -var File_openconfig_openconfig_proto protoreflect.FileDescriptor - -var file_openconfig_openconfig_proto_rawDesc = []byte{ - 0x0a, 0x1b, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x6f, 0x70, 0x65, - 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0a, 0x6f, - 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x38, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x2f, 0x79, 0x67, 0x6f, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x79, 0x77, 0x72, 0x61, - 0x70, 0x70, 0x65, 0x72, 0x2f, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x1a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x79, 0x67, 0x6f, 0x74, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x79, 0x65, 0x78, 0x74, 0x2f, 0x79, 0x65, 0x78, 0x74, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x3c, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x22, 0x69, 0x0a, 0x06, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5f, 0x0a, - 0x0a, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x18, 0xbe, 0xf4, 0xc5, 0x28, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x73, 0x42, 0x0e, 0x82, 0x41, 0x0b, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x73, 0x52, 0x0a, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_openconfig_openconfig_proto_rawDescOnce sync.Once - file_openconfig_openconfig_proto_rawDescData = file_openconfig_openconfig_proto_rawDesc -) - -func file_openconfig_openconfig_proto_rawDescGZIP() []byte { - file_openconfig_openconfig_proto_rawDescOnce.Do(func() { - file_openconfig_openconfig_proto_rawDescData = protoimpl.X.CompressGZIP(file_openconfig_openconfig_proto_rawDescData) - }) - return file_openconfig_openconfig_proto_rawDescData -} - -var file_openconfig_openconfig_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_openconfig_openconfig_proto_goTypes = []interface{}{ - (*Device)(nil), // 0: openconfig.Device - (*openconfig_interfaces.Interfaces)(nil), // 1: openconfig.openconfig_interfaces.Interfaces -} -var file_openconfig_openconfig_proto_depIdxs = []int32{ - 1, // 0: openconfig.Device.interfaces:type_name -> openconfig.openconfig_interfaces.Interfaces - 1, // [1:1] is the sub-list for method output_type - 1, // [1:1] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name -} - -func init() { file_openconfig_openconfig_proto_init() } -func file_openconfig_openconfig_proto_init() { - if File_openconfig_openconfig_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_openconfig_openconfig_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Device); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_openconfig_openconfig_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_openconfig_openconfig_proto_goTypes, - DependencyIndexes: file_openconfig_openconfig_proto_depIdxs, - MessageInfos: file_openconfig_openconfig_proto_msgTypes, - }.Build() - File_openconfig_openconfig_proto = out.File - file_openconfig_openconfig_proto_rawDesc = nil - file_openconfig_openconfig_proto_goTypes = nil - file_openconfig_openconfig_proto_depIdxs = nil -} diff --git a/api/proto/openconfig/openconfig.proto b/api/proto/openconfig/openconfig.proto deleted file mode 100644 index c2b37bb0386d95ed45beea0ca8ee920049928253..0000000000000000000000000000000000000000 --- a/api/proto/openconfig/openconfig.proto +++ /dev/null @@ -1,20 +0,0 @@ -// openconfig is generated by proto_generator as a protobuf -// representation of a YANG schema. -// -// Input schema modules: -// - ../yang-models/models/openconfig/release/models/interfaces/openconfig-interfaces.yang -// Include paths: -// - ../yang-models/models/... -syntax = "proto3"; - -package openconfig; -option go_package = "code.fbi.h-da.de/cocsn/gosdn"; - - -import "github.com/openconfig/ygot/proto/ywrapper/ywrapper.proto"; -import "github.com/openconfig/ygot/proto/yext/yext.proto"; -import "openconfig/openconfig_interfaces/openconfig_interfaces.proto"; - -message Device { - openconfig_interfaces.Interfaces interfaces = 85031486 [(yext.schemapath) = "/interfaces"]; -} diff --git a/api/proto/openconfig/openconfig_interfaces/openconfig_interfaces.pb.go b/api/proto/openconfig/openconfig_interfaces/openconfig_interfaces.pb.go deleted file mode 100644 index 26ca33432b263e485c6c7ca994bb76caf72992d6..0000000000000000000000000000000000000000 --- a/api/proto/openconfig/openconfig_interfaces/openconfig_interfaces.pb.go +++ /dev/null @@ -1,2620 +0,0 @@ -// openconfig.openconfig_interfaces is generated by proto_generator as a protobuf -// representation of a YANG schema. -// -// Input schema modules: -// - ../yang-models/models/openconfig/release/models/interfaces/openconfig-interfaces.yang -// Include paths: -// - ../yang-models/models/... - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.25.0-devel -// protoc v3.13.0 -// source: openconfig/openconfig_interfaces/openconfig_interfaces.proto - -package openconfig_openconfig_interfaces - -import ( - enums "code.fbi.h-da.de/cocsn/gosdn/api/proto/openconfig/enums" - proto "github.com/golang/protobuf/proto" - _ "github.com/openconfig/ygot/proto/yext" - ywrapper "github.com/openconfig/ygot/proto/ywrapper" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// This is a compile-time assertion that a sufficiently up-to-date version -// of the legacy proto package is being used. -const _ = proto.ProtoPackageIsVersion4 - -type Interfaces_Interface_State_AdminStatus int32 - -const ( - Interfaces_Interface_State_ADMINSTATUS_UNSET Interfaces_Interface_State_AdminStatus = 0 - Interfaces_Interface_State_ADMINSTATUS_UP Interfaces_Interface_State_AdminStatus = 1 - Interfaces_Interface_State_ADMINSTATUS_DOWN Interfaces_Interface_State_AdminStatus = 2 - Interfaces_Interface_State_ADMINSTATUS_TESTING Interfaces_Interface_State_AdminStatus = 3 -) - -// Enum value maps for Interfaces_Interface_State_AdminStatus. -var ( - Interfaces_Interface_State_AdminStatus_name = map[int32]string{ - 0: "ADMINSTATUS_UNSET", - 1: "ADMINSTATUS_UP", - 2: "ADMINSTATUS_DOWN", - 3: "ADMINSTATUS_TESTING", - } - Interfaces_Interface_State_AdminStatus_value = map[string]int32{ - "ADMINSTATUS_UNSET": 0, - "ADMINSTATUS_UP": 1, - "ADMINSTATUS_DOWN": 2, - "ADMINSTATUS_TESTING": 3, - } -) - -func (x Interfaces_Interface_State_AdminStatus) Enum() *Interfaces_Interface_State_AdminStatus { - p := new(Interfaces_Interface_State_AdminStatus) - *p = x - return p -} - -func (x Interfaces_Interface_State_AdminStatus) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (Interfaces_Interface_State_AdminStatus) Descriptor() protoreflect.EnumDescriptor { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_enumTypes[0].Descriptor() -} - -func (Interfaces_Interface_State_AdminStatus) Type() protoreflect.EnumType { - return &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_enumTypes[0] -} - -func (x Interfaces_Interface_State_AdminStatus) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use Interfaces_Interface_State_AdminStatus.Descriptor instead. -func (Interfaces_Interface_State_AdminStatus) EnumDescriptor() ([]byte, []int) { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescGZIP(), []int{0, 0, 2, 0} -} - -type Interfaces_Interface_State_OperStatus int32 - -const ( - Interfaces_Interface_State_OPERSTATUS_UNSET Interfaces_Interface_State_OperStatus = 0 - Interfaces_Interface_State_OPERSTATUS_UP Interfaces_Interface_State_OperStatus = 2 - Interfaces_Interface_State_OPERSTATUS_DOWN Interfaces_Interface_State_OperStatus = 3 - Interfaces_Interface_State_OPERSTATUS_TESTING Interfaces_Interface_State_OperStatus = 4 - Interfaces_Interface_State_OPERSTATUS_UNKNOWN Interfaces_Interface_State_OperStatus = 5 - Interfaces_Interface_State_OPERSTATUS_DORMANT Interfaces_Interface_State_OperStatus = 6 - Interfaces_Interface_State_OPERSTATUS_NOT_PRESENT Interfaces_Interface_State_OperStatus = 7 - Interfaces_Interface_State_OPERSTATUS_LOWER_LAYER_DOWN Interfaces_Interface_State_OperStatus = 8 -) - -// Enum value maps for Interfaces_Interface_State_OperStatus. -var ( - Interfaces_Interface_State_OperStatus_name = map[int32]string{ - 0: "OPERSTATUS_UNSET", - 2: "OPERSTATUS_UP", - 3: "OPERSTATUS_DOWN", - 4: "OPERSTATUS_TESTING", - 5: "OPERSTATUS_UNKNOWN", - 6: "OPERSTATUS_DORMANT", - 7: "OPERSTATUS_NOT_PRESENT", - 8: "OPERSTATUS_LOWER_LAYER_DOWN", - } - Interfaces_Interface_State_OperStatus_value = map[string]int32{ - "OPERSTATUS_UNSET": 0, - "OPERSTATUS_UP": 2, - "OPERSTATUS_DOWN": 3, - "OPERSTATUS_TESTING": 4, - "OPERSTATUS_UNKNOWN": 5, - "OPERSTATUS_DORMANT": 6, - "OPERSTATUS_NOT_PRESENT": 7, - "OPERSTATUS_LOWER_LAYER_DOWN": 8, - } -) - -func (x Interfaces_Interface_State_OperStatus) Enum() *Interfaces_Interface_State_OperStatus { - p := new(Interfaces_Interface_State_OperStatus) - *p = x - return p -} - -func (x Interfaces_Interface_State_OperStatus) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (Interfaces_Interface_State_OperStatus) Descriptor() protoreflect.EnumDescriptor { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_enumTypes[1].Descriptor() -} - -func (Interfaces_Interface_State_OperStatus) Type() protoreflect.EnumType { - return &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_enumTypes[1] -} - -func (x Interfaces_Interface_State_OperStatus) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use Interfaces_Interface_State_OperStatus.Descriptor instead. -func (Interfaces_Interface_State_OperStatus) EnumDescriptor() ([]byte, []int) { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescGZIP(), []int{0, 0, 2, 1} -} - -type Interfaces_Interface_Subinterfaces_Subinterface_State_AdminStatus int32 - -const ( - Interfaces_Interface_Subinterfaces_Subinterface_State_ADMINSTATUS_UNSET Interfaces_Interface_Subinterfaces_Subinterface_State_AdminStatus = 0 - Interfaces_Interface_Subinterfaces_Subinterface_State_ADMINSTATUS_UP Interfaces_Interface_Subinterfaces_Subinterface_State_AdminStatus = 1 - Interfaces_Interface_Subinterfaces_Subinterface_State_ADMINSTATUS_DOWN Interfaces_Interface_Subinterfaces_Subinterface_State_AdminStatus = 2 - Interfaces_Interface_Subinterfaces_Subinterface_State_ADMINSTATUS_TESTING Interfaces_Interface_Subinterfaces_Subinterface_State_AdminStatus = 3 -) - -// Enum value maps for Interfaces_Interface_Subinterfaces_Subinterface_State_AdminStatus. -var ( - Interfaces_Interface_Subinterfaces_Subinterface_State_AdminStatus_name = map[int32]string{ - 0: "ADMINSTATUS_UNSET", - 1: "ADMINSTATUS_UP", - 2: "ADMINSTATUS_DOWN", - 3: "ADMINSTATUS_TESTING", - } - Interfaces_Interface_Subinterfaces_Subinterface_State_AdminStatus_value = map[string]int32{ - "ADMINSTATUS_UNSET": 0, - "ADMINSTATUS_UP": 1, - "ADMINSTATUS_DOWN": 2, - "ADMINSTATUS_TESTING": 3, - } -) - -func (x Interfaces_Interface_Subinterfaces_Subinterface_State_AdminStatus) Enum() *Interfaces_Interface_Subinterfaces_Subinterface_State_AdminStatus { - p := new(Interfaces_Interface_Subinterfaces_Subinterface_State_AdminStatus) - *p = x - return p -} - -func (x Interfaces_Interface_Subinterfaces_Subinterface_State_AdminStatus) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (Interfaces_Interface_Subinterfaces_Subinterface_State_AdminStatus) Descriptor() protoreflect.EnumDescriptor { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_enumTypes[2].Descriptor() -} - -func (Interfaces_Interface_Subinterfaces_Subinterface_State_AdminStatus) Type() protoreflect.EnumType { - return &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_enumTypes[2] -} - -func (x Interfaces_Interface_Subinterfaces_Subinterface_State_AdminStatus) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use Interfaces_Interface_Subinterfaces_Subinterface_State_AdminStatus.Descriptor instead. -func (Interfaces_Interface_Subinterfaces_Subinterface_State_AdminStatus) EnumDescriptor() ([]byte, []int) { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescGZIP(), []int{0, 0, 3, 0, 1, 0} -} - -type Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus int32 - -const ( - Interfaces_Interface_Subinterfaces_Subinterface_State_OPERSTATUS_UNSET Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus = 0 - Interfaces_Interface_Subinterfaces_Subinterface_State_OPERSTATUS_UP Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus = 2 - Interfaces_Interface_Subinterfaces_Subinterface_State_OPERSTATUS_DOWN Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus = 3 - Interfaces_Interface_Subinterfaces_Subinterface_State_OPERSTATUS_TESTING Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus = 4 - Interfaces_Interface_Subinterfaces_Subinterface_State_OPERSTATUS_UNKNOWN Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus = 5 - Interfaces_Interface_Subinterfaces_Subinterface_State_OPERSTATUS_DORMANT Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus = 6 - Interfaces_Interface_Subinterfaces_Subinterface_State_OPERSTATUS_NOT_PRESENT Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus = 7 - Interfaces_Interface_Subinterfaces_Subinterface_State_OPERSTATUS_LOWER_LAYER_DOWN Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus = 8 -) - -// Enum value maps for Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus. -var ( - Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus_name = map[int32]string{ - 0: "OPERSTATUS_UNSET", - 2: "OPERSTATUS_UP", - 3: "OPERSTATUS_DOWN", - 4: "OPERSTATUS_TESTING", - 5: "OPERSTATUS_UNKNOWN", - 6: "OPERSTATUS_DORMANT", - 7: "OPERSTATUS_NOT_PRESENT", - 8: "OPERSTATUS_LOWER_LAYER_DOWN", - } - Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus_value = map[string]int32{ - "OPERSTATUS_UNSET": 0, - "OPERSTATUS_UP": 2, - "OPERSTATUS_DOWN": 3, - "OPERSTATUS_TESTING": 4, - "OPERSTATUS_UNKNOWN": 5, - "OPERSTATUS_DORMANT": 6, - "OPERSTATUS_NOT_PRESENT": 7, - "OPERSTATUS_LOWER_LAYER_DOWN": 8, - } -) - -func (x Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus) Enum() *Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus { - p := new(Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus) - *p = x - return p -} - -func (x Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus) Descriptor() protoreflect.EnumDescriptor { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_enumTypes[3].Descriptor() -} - -func (Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus) Type() protoreflect.EnumType { - return &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_enumTypes[3] -} - -func (x Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus.Descriptor instead. -func (Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus) EnumDescriptor() ([]byte, []int) { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescGZIP(), []int{0, 0, 3, 0, 1, 1} -} - -type Interfaces struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Interface []*Interfaces_InterfaceKey `protobuf:"bytes,422482938,rep,name=interface,proto3" json:"interface,omitempty"` -} - -func (x *Interfaces) Reset() { - *x = Interfaces{} - if protoimpl.UnsafeEnabled { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Interfaces) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Interfaces) ProtoMessage() {} - -func (x *Interfaces) ProtoReflect() protoreflect.Message { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Interfaces.ProtoReflect.Descriptor instead. -func (*Interfaces) Descriptor() ([]byte, []int) { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescGZIP(), []int{0} -} - -func (x *Interfaces) GetInterface() []*Interfaces_InterfaceKey { - if x != nil { - return x.Interface - } - return nil -} - -type Interfaces_Interface struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Config *Interfaces_Interface_Config `protobuf:"bytes,334174827,opt,name=config,proto3" json:"config,omitempty"` - HoldTime *Interfaces_Interface_HoldTime `protobuf:"bytes,175931092,opt,name=hold_time,json=holdTime,proto3" json:"hold_time,omitempty"` - State *Interfaces_Interface_State `protobuf:"bytes,387556140,opt,name=state,proto3" json:"state,omitempty"` - Subinterfaces *Interfaces_Interface_Subinterfaces `protobuf:"bytes,327798165,opt,name=subinterfaces,proto3" json:"subinterfaces,omitempty"` -} - -func (x *Interfaces_Interface) Reset() { - *x = Interfaces_Interface{} - if protoimpl.UnsafeEnabled { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Interfaces_Interface) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Interfaces_Interface) ProtoMessage() {} - -func (x *Interfaces_Interface) ProtoReflect() protoreflect.Message { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Interfaces_Interface.ProtoReflect.Descriptor instead. -func (*Interfaces_Interface) Descriptor() ([]byte, []int) { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescGZIP(), []int{0, 0} -} - -func (x *Interfaces_Interface) GetConfig() *Interfaces_Interface_Config { - if x != nil { - return x.Config - } - return nil -} - -func (x *Interfaces_Interface) GetHoldTime() *Interfaces_Interface_HoldTime { - if x != nil { - return x.HoldTime - } - return nil -} - -func (x *Interfaces_Interface) GetState() *Interfaces_Interface_State { - if x != nil { - return x.State - } - return nil -} - -func (x *Interfaces_Interface) GetSubinterfaces() *Interfaces_Interface_Subinterfaces { - if x != nil { - return x.Subinterfaces - } - return nil -} - -type Interfaces_InterfaceKey struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Interface *Interfaces_Interface `protobuf:"bytes,2,opt,name=interface,proto3" json:"interface,omitempty"` -} - -func (x *Interfaces_InterfaceKey) Reset() { - *x = Interfaces_InterfaceKey{} - if protoimpl.UnsafeEnabled { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Interfaces_InterfaceKey) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Interfaces_InterfaceKey) ProtoMessage() {} - -func (x *Interfaces_InterfaceKey) ProtoReflect() protoreflect.Message { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Interfaces_InterfaceKey.ProtoReflect.Descriptor instead. -func (*Interfaces_InterfaceKey) Descriptor() ([]byte, []int) { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescGZIP(), []int{0, 1} -} - -func (x *Interfaces_InterfaceKey) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *Interfaces_InterfaceKey) GetInterface() *Interfaces_Interface { - if x != nil { - return x.Interface - } - return nil -} - -type Interfaces_Interface_Config struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Description *ywrapper.StringValue `protobuf:"bytes,418535860,opt,name=description,proto3" json:"description,omitempty"` - Enabled *ywrapper.BoolValue `protobuf:"bytes,37224301,opt,name=enabled,proto3" json:"enabled,omitempty"` - LoopbackMode *ywrapper.BoolValue `protobuf:"bytes,253516347,opt,name=loopback_mode,json=loopbackMode,proto3" json:"loopback_mode,omitempty"` - Mtu *ywrapper.UintValue `protobuf:"bytes,376210342,opt,name=mtu,proto3" json:"mtu,omitempty"` - Name *ywrapper.StringValue `protobuf:"bytes,51804187,opt,name=name,proto3" json:"name,omitempty"` - Type enums.IETFInterfacesInterfaceType `protobuf:"varint,144596894,opt,name=type,proto3,enum=openconfig.enums.IETFInterfacesInterfaceType" json:"type,omitempty"` -} - -func (x *Interfaces_Interface_Config) Reset() { - *x = Interfaces_Interface_Config{} - if protoimpl.UnsafeEnabled { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Interfaces_Interface_Config) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Interfaces_Interface_Config) ProtoMessage() {} - -func (x *Interfaces_Interface_Config) ProtoReflect() protoreflect.Message { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Interfaces_Interface_Config.ProtoReflect.Descriptor instead. -func (*Interfaces_Interface_Config) Descriptor() ([]byte, []int) { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescGZIP(), []int{0, 0, 0} -} - -func (x *Interfaces_Interface_Config) GetDescription() *ywrapper.StringValue { - if x != nil { - return x.Description - } - return nil -} - -func (x *Interfaces_Interface_Config) GetEnabled() *ywrapper.BoolValue { - if x != nil { - return x.Enabled - } - return nil -} - -func (x *Interfaces_Interface_Config) GetLoopbackMode() *ywrapper.BoolValue { - if x != nil { - return x.LoopbackMode - } - return nil -} - -func (x *Interfaces_Interface_Config) GetMtu() *ywrapper.UintValue { - if x != nil { - return x.Mtu - } - return nil -} - -func (x *Interfaces_Interface_Config) GetName() *ywrapper.StringValue { - if x != nil { - return x.Name - } - return nil -} - -func (x *Interfaces_Interface_Config) GetType() enums.IETFInterfacesInterfaceType { - if x != nil { - return x.Type - } - return enums.IETFInterfacesInterfaceType_IETFINTERFACESINTERFACETYPE_UNSET -} - -type Interfaces_Interface_HoldTime struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Config *Interfaces_Interface_HoldTime_Config `protobuf:"bytes,316512729,opt,name=config,proto3" json:"config,omitempty"` - State *Interfaces_Interface_HoldTime_State `protobuf:"bytes,483010990,opt,name=state,proto3" json:"state,omitempty"` -} - -func (x *Interfaces_Interface_HoldTime) Reset() { - *x = Interfaces_Interface_HoldTime{} - if protoimpl.UnsafeEnabled { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Interfaces_Interface_HoldTime) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Interfaces_Interface_HoldTime) ProtoMessage() {} - -func (x *Interfaces_Interface_HoldTime) ProtoReflect() protoreflect.Message { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Interfaces_Interface_HoldTime.ProtoReflect.Descriptor instead. -func (*Interfaces_Interface_HoldTime) Descriptor() ([]byte, []int) { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescGZIP(), []int{0, 0, 1} -} - -func (x *Interfaces_Interface_HoldTime) GetConfig() *Interfaces_Interface_HoldTime_Config { - if x != nil { - return x.Config - } - return nil -} - -func (x *Interfaces_Interface_HoldTime) GetState() *Interfaces_Interface_HoldTime_State { - if x != nil { - return x.State - } - return nil -} - -type Interfaces_Interface_State struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - AdminStatus Interfaces_Interface_State_AdminStatus `protobuf:"varint,474494763,opt,name=admin_status,json=adminStatus,proto3,enum=openconfig.openconfig_interfaces.Interfaces_Interface_State_AdminStatus" json:"admin_status,omitempty"` - Counters *Interfaces_Interface_State_Counters `protobuf:"bytes,83645964,opt,name=counters,proto3" json:"counters,omitempty"` - Description *ywrapper.StringValue `protobuf:"bytes,389435287,opt,name=description,proto3" json:"description,omitempty"` - Enabled *ywrapper.BoolValue `protobuf:"bytes,330927518,opt,name=enabled,proto3" json:"enabled,omitempty"` - Ifindex *ywrapper.UintValue `protobuf:"bytes,116108202,opt,name=ifindex,proto3" json:"ifindex,omitempty"` - LastChange *ywrapper.UintValue `protobuf:"bytes,127348880,opt,name=last_change,json=lastChange,proto3" json:"last_change,omitempty"` - Logical *ywrapper.BoolValue `protobuf:"bytes,440460216,opt,name=logical,proto3" json:"logical,omitempty"` - LoopbackMode *ywrapper.BoolValue `protobuf:"bytes,372935512,opt,name=loopback_mode,json=loopbackMode,proto3" json:"loopback_mode,omitempty"` - Mtu *ywrapper.UintValue `protobuf:"bytes,96390485,opt,name=mtu,proto3" json:"mtu,omitempty"` - Name *ywrapper.StringValue `protobuf:"bytes,503495278,opt,name=name,proto3" json:"name,omitempty"` - OperStatus Interfaces_Interface_State_OperStatus `protobuf:"varint,470394226,opt,name=oper_status,json=operStatus,proto3,enum=openconfig.openconfig_interfaces.Interfaces_Interface_State_OperStatus" json:"oper_status,omitempty"` - Type enums.IETFInterfacesInterfaceType `protobuf:"varint,358148579,opt,name=type,proto3,enum=openconfig.enums.IETFInterfacesInterfaceType" json:"type,omitempty"` -} - -func (x *Interfaces_Interface_State) Reset() { - *x = Interfaces_Interface_State{} - if protoimpl.UnsafeEnabled { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Interfaces_Interface_State) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Interfaces_Interface_State) ProtoMessage() {} - -func (x *Interfaces_Interface_State) ProtoReflect() protoreflect.Message { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Interfaces_Interface_State.ProtoReflect.Descriptor instead. -func (*Interfaces_Interface_State) Descriptor() ([]byte, []int) { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescGZIP(), []int{0, 0, 2} -} - -func (x *Interfaces_Interface_State) GetAdminStatus() Interfaces_Interface_State_AdminStatus { - if x != nil { - return x.AdminStatus - } - return Interfaces_Interface_State_ADMINSTATUS_UNSET -} - -func (x *Interfaces_Interface_State) GetCounters() *Interfaces_Interface_State_Counters { - if x != nil { - return x.Counters - } - return nil -} - -func (x *Interfaces_Interface_State) GetDescription() *ywrapper.StringValue { - if x != nil { - return x.Description - } - return nil -} - -func (x *Interfaces_Interface_State) GetEnabled() *ywrapper.BoolValue { - if x != nil { - return x.Enabled - } - return nil -} - -func (x *Interfaces_Interface_State) GetIfindex() *ywrapper.UintValue { - if x != nil { - return x.Ifindex - } - return nil -} - -func (x *Interfaces_Interface_State) GetLastChange() *ywrapper.UintValue { - if x != nil { - return x.LastChange - } - return nil -} - -func (x *Interfaces_Interface_State) GetLogical() *ywrapper.BoolValue { - if x != nil { - return x.Logical - } - return nil -} - -func (x *Interfaces_Interface_State) GetLoopbackMode() *ywrapper.BoolValue { - if x != nil { - return x.LoopbackMode - } - return nil -} - -func (x *Interfaces_Interface_State) GetMtu() *ywrapper.UintValue { - if x != nil { - return x.Mtu - } - return nil -} - -func (x *Interfaces_Interface_State) GetName() *ywrapper.StringValue { - if x != nil { - return x.Name - } - return nil -} - -func (x *Interfaces_Interface_State) GetOperStatus() Interfaces_Interface_State_OperStatus { - if x != nil { - return x.OperStatus - } - return Interfaces_Interface_State_OPERSTATUS_UNSET -} - -func (x *Interfaces_Interface_State) GetType() enums.IETFInterfacesInterfaceType { - if x != nil { - return x.Type - } - return enums.IETFInterfacesInterfaceType_IETFINTERFACESINTERFACETYPE_UNSET -} - -type Interfaces_Interface_Subinterfaces struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Subinterface []*Interfaces_Interface_Subinterfaces_SubinterfaceKey `protobuf:"bytes,464802819,rep,name=subinterface,proto3" json:"subinterface,omitempty"` -} - -func (x *Interfaces_Interface_Subinterfaces) Reset() { - *x = Interfaces_Interface_Subinterfaces{} - if protoimpl.UnsafeEnabled { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Interfaces_Interface_Subinterfaces) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Interfaces_Interface_Subinterfaces) ProtoMessage() {} - -func (x *Interfaces_Interface_Subinterfaces) ProtoReflect() protoreflect.Message { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Interfaces_Interface_Subinterfaces.ProtoReflect.Descriptor instead. -func (*Interfaces_Interface_Subinterfaces) Descriptor() ([]byte, []int) { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescGZIP(), []int{0, 0, 3} -} - -func (x *Interfaces_Interface_Subinterfaces) GetSubinterface() []*Interfaces_Interface_Subinterfaces_SubinterfaceKey { - if x != nil { - return x.Subinterface - } - return nil -} - -type Interfaces_Interface_HoldTime_Config struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Down *ywrapper.UintValue `protobuf:"bytes,171181656,opt,name=down,proto3" json:"down,omitempty"` - Up *ywrapper.UintValue `protobuf:"bytes,62026235,opt,name=up,proto3" json:"up,omitempty"` -} - -func (x *Interfaces_Interface_HoldTime_Config) Reset() { - *x = Interfaces_Interface_HoldTime_Config{} - if protoimpl.UnsafeEnabled { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Interfaces_Interface_HoldTime_Config) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Interfaces_Interface_HoldTime_Config) ProtoMessage() {} - -func (x *Interfaces_Interface_HoldTime_Config) ProtoReflect() protoreflect.Message { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Interfaces_Interface_HoldTime_Config.ProtoReflect.Descriptor instead. -func (*Interfaces_Interface_HoldTime_Config) Descriptor() ([]byte, []int) { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescGZIP(), []int{0, 0, 1, 0} -} - -func (x *Interfaces_Interface_HoldTime_Config) GetDown() *ywrapper.UintValue { - if x != nil { - return x.Down - } - return nil -} - -func (x *Interfaces_Interface_HoldTime_Config) GetUp() *ywrapper.UintValue { - if x != nil { - return x.Up - } - return nil -} - -type Interfaces_Interface_HoldTime_State struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Down *ywrapper.UintValue `protobuf:"bytes,167887721,opt,name=down,proto3" json:"down,omitempty"` - Up *ywrapper.UintValue `protobuf:"bytes,223847598,opt,name=up,proto3" json:"up,omitempty"` -} - -func (x *Interfaces_Interface_HoldTime_State) Reset() { - *x = Interfaces_Interface_HoldTime_State{} - if protoimpl.UnsafeEnabled { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Interfaces_Interface_HoldTime_State) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Interfaces_Interface_HoldTime_State) ProtoMessage() {} - -func (x *Interfaces_Interface_HoldTime_State) ProtoReflect() protoreflect.Message { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Interfaces_Interface_HoldTime_State.ProtoReflect.Descriptor instead. -func (*Interfaces_Interface_HoldTime_State) Descriptor() ([]byte, []int) { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescGZIP(), []int{0, 0, 1, 1} -} - -func (x *Interfaces_Interface_HoldTime_State) GetDown() *ywrapper.UintValue { - if x != nil { - return x.Down - } - return nil -} - -func (x *Interfaces_Interface_HoldTime_State) GetUp() *ywrapper.UintValue { - if x != nil { - return x.Up - } - return nil -} - -type Interfaces_Interface_State_Counters struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - CarrierTransitions *ywrapper.UintValue `protobuf:"bytes,270803130,opt,name=carrier_transitions,json=carrierTransitions,proto3" json:"carrier_transitions,omitempty"` - InBroadcastPkts *ywrapper.UintValue `protobuf:"bytes,280201989,opt,name=in_broadcast_pkts,json=inBroadcastPkts,proto3" json:"in_broadcast_pkts,omitempty"` - InDiscards *ywrapper.UintValue `protobuf:"bytes,11979514,opt,name=in_discards,json=inDiscards,proto3" json:"in_discards,omitempty"` - InErrors *ywrapper.UintValue `protobuf:"bytes,456697578,opt,name=in_errors,json=inErrors,proto3" json:"in_errors,omitempty"` - InFcsErrors *ywrapper.UintValue `protobuf:"bytes,501559027,opt,name=in_fcs_errors,json=inFcsErrors,proto3" json:"in_fcs_errors,omitempty"` - InMulticastPkts *ywrapper.UintValue `protobuf:"bytes,113269128,opt,name=in_multicast_pkts,json=inMulticastPkts,proto3" json:"in_multicast_pkts,omitempty"` - InOctets *ywrapper.UintValue `protobuf:"bytes,333138891,opt,name=in_octets,json=inOctets,proto3" json:"in_octets,omitempty"` - InPkts *ywrapper.UintValue `protobuf:"bytes,412843491,opt,name=in_pkts,json=inPkts,proto3" json:"in_pkts,omitempty"` - InUnicastPkts *ywrapper.UintValue `protobuf:"bytes,272792307,opt,name=in_unicast_pkts,json=inUnicastPkts,proto3" json:"in_unicast_pkts,omitempty"` - InUnknownProtos *ywrapper.UintValue `protobuf:"bytes,241475497,opt,name=in_unknown_protos,json=inUnknownProtos,proto3" json:"in_unknown_protos,omitempty"` - LastClear *ywrapper.UintValue `protobuf:"bytes,186014919,opt,name=last_clear,json=lastClear,proto3" json:"last_clear,omitempty"` - OutBroadcastPkts *ywrapper.UintValue `protobuf:"bytes,338589668,opt,name=out_broadcast_pkts,json=outBroadcastPkts,proto3" json:"out_broadcast_pkts,omitempty"` - OutDiscards *ywrapper.UintValue `protobuf:"bytes,254055111,opt,name=out_discards,json=outDiscards,proto3" json:"out_discards,omitempty"` - OutErrors *ywrapper.UintValue `protobuf:"bytes,471103047,opt,name=out_errors,json=outErrors,proto3" json:"out_errors,omitempty"` - OutMulticastPkts *ywrapper.UintValue `protobuf:"bytes,457840757,opt,name=out_multicast_pkts,json=outMulticastPkts,proto3" json:"out_multicast_pkts,omitempty"` - OutOctets *ywrapper.UintValue `protobuf:"bytes,201005514,opt,name=out_octets,json=outOctets,proto3" json:"out_octets,omitempty"` - OutPkts *ywrapper.UintValue `protobuf:"bytes,437582090,opt,name=out_pkts,json=outPkts,proto3" json:"out_pkts,omitempty"` - OutUnicastPkts *ywrapper.UintValue `protobuf:"bytes,36542246,opt,name=out_unicast_pkts,json=outUnicastPkts,proto3" json:"out_unicast_pkts,omitempty"` -} - -func (x *Interfaces_Interface_State_Counters) Reset() { - *x = Interfaces_Interface_State_Counters{} - if protoimpl.UnsafeEnabled { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Interfaces_Interface_State_Counters) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Interfaces_Interface_State_Counters) ProtoMessage() {} - -func (x *Interfaces_Interface_State_Counters) ProtoReflect() protoreflect.Message { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Interfaces_Interface_State_Counters.ProtoReflect.Descriptor instead. -func (*Interfaces_Interface_State_Counters) Descriptor() ([]byte, []int) { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescGZIP(), []int{0, 0, 2, 0} -} - -func (x *Interfaces_Interface_State_Counters) GetCarrierTransitions() *ywrapper.UintValue { - if x != nil { - return x.CarrierTransitions - } - return nil -} - -func (x *Interfaces_Interface_State_Counters) GetInBroadcastPkts() *ywrapper.UintValue { - if x != nil { - return x.InBroadcastPkts - } - return nil -} - -func (x *Interfaces_Interface_State_Counters) GetInDiscards() *ywrapper.UintValue { - if x != nil { - return x.InDiscards - } - return nil -} - -func (x *Interfaces_Interface_State_Counters) GetInErrors() *ywrapper.UintValue { - if x != nil { - return x.InErrors - } - return nil -} - -func (x *Interfaces_Interface_State_Counters) GetInFcsErrors() *ywrapper.UintValue { - if x != nil { - return x.InFcsErrors - } - return nil -} - -func (x *Interfaces_Interface_State_Counters) GetInMulticastPkts() *ywrapper.UintValue { - if x != nil { - return x.InMulticastPkts - } - return nil -} - -func (x *Interfaces_Interface_State_Counters) GetInOctets() *ywrapper.UintValue { - if x != nil { - return x.InOctets - } - return nil -} - -func (x *Interfaces_Interface_State_Counters) GetInPkts() *ywrapper.UintValue { - if x != nil { - return x.InPkts - } - return nil -} - -func (x *Interfaces_Interface_State_Counters) GetInUnicastPkts() *ywrapper.UintValue { - if x != nil { - return x.InUnicastPkts - } - return nil -} - -func (x *Interfaces_Interface_State_Counters) GetInUnknownProtos() *ywrapper.UintValue { - if x != nil { - return x.InUnknownProtos - } - return nil -} - -func (x *Interfaces_Interface_State_Counters) GetLastClear() *ywrapper.UintValue { - if x != nil { - return x.LastClear - } - return nil -} - -func (x *Interfaces_Interface_State_Counters) GetOutBroadcastPkts() *ywrapper.UintValue { - if x != nil { - return x.OutBroadcastPkts - } - return nil -} - -func (x *Interfaces_Interface_State_Counters) GetOutDiscards() *ywrapper.UintValue { - if x != nil { - return x.OutDiscards - } - return nil -} - -func (x *Interfaces_Interface_State_Counters) GetOutErrors() *ywrapper.UintValue { - if x != nil { - return x.OutErrors - } - return nil -} - -func (x *Interfaces_Interface_State_Counters) GetOutMulticastPkts() *ywrapper.UintValue { - if x != nil { - return x.OutMulticastPkts - } - return nil -} - -func (x *Interfaces_Interface_State_Counters) GetOutOctets() *ywrapper.UintValue { - if x != nil { - return x.OutOctets - } - return nil -} - -func (x *Interfaces_Interface_State_Counters) GetOutPkts() *ywrapper.UintValue { - if x != nil { - return x.OutPkts - } - return nil -} - -func (x *Interfaces_Interface_State_Counters) GetOutUnicastPkts() *ywrapper.UintValue { - if x != nil { - return x.OutUnicastPkts - } - return nil -} - -type Interfaces_Interface_Subinterfaces_Subinterface struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Config *Interfaces_Interface_Subinterfaces_Subinterface_Config `protobuf:"bytes,175001476,opt,name=config,proto3" json:"config,omitempty"` - State *Interfaces_Interface_Subinterfaces_Subinterface_State `protobuf:"bytes,501974173,opt,name=state,proto3" json:"state,omitempty"` -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface) Reset() { - *x = Interfaces_Interface_Subinterfaces_Subinterface{} - if protoimpl.UnsafeEnabled { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Interfaces_Interface_Subinterfaces_Subinterface) ProtoMessage() {} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface) ProtoReflect() protoreflect.Message { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Interfaces_Interface_Subinterfaces_Subinterface.ProtoReflect.Descriptor instead. -func (*Interfaces_Interface_Subinterfaces_Subinterface) Descriptor() ([]byte, []int) { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescGZIP(), []int{0, 0, 3, 0} -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface) GetConfig() *Interfaces_Interface_Subinterfaces_Subinterface_Config { - if x != nil { - return x.Config - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface) GetState() *Interfaces_Interface_Subinterfaces_Subinterface_State { - if x != nil { - return x.State - } - return nil -} - -type Interfaces_Interface_Subinterfaces_SubinterfaceKey struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Index uint64 `protobuf:"varint,1,opt,name=index,proto3" json:"index,omitempty"` - Subinterface *Interfaces_Interface_Subinterfaces_Subinterface `protobuf:"bytes,2,opt,name=subinterface,proto3" json:"subinterface,omitempty"` -} - -func (x *Interfaces_Interface_Subinterfaces_SubinterfaceKey) Reset() { - *x = Interfaces_Interface_Subinterfaces_SubinterfaceKey{} - if protoimpl.UnsafeEnabled { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Interfaces_Interface_Subinterfaces_SubinterfaceKey) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Interfaces_Interface_Subinterfaces_SubinterfaceKey) ProtoMessage() {} - -func (x *Interfaces_Interface_Subinterfaces_SubinterfaceKey) ProtoReflect() protoreflect.Message { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[11] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Interfaces_Interface_Subinterfaces_SubinterfaceKey.ProtoReflect.Descriptor instead. -func (*Interfaces_Interface_Subinterfaces_SubinterfaceKey) Descriptor() ([]byte, []int) { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescGZIP(), []int{0, 0, 3, 1} -} - -func (x *Interfaces_Interface_Subinterfaces_SubinterfaceKey) GetIndex() uint64 { - if x != nil { - return x.Index - } - return 0 -} - -func (x *Interfaces_Interface_Subinterfaces_SubinterfaceKey) GetSubinterface() *Interfaces_Interface_Subinterfaces_Subinterface { - if x != nil { - return x.Subinterface - } - return nil -} - -type Interfaces_Interface_Subinterfaces_Subinterface_Config struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Description *ywrapper.StringValue `protobuf:"bytes,280671199,opt,name=description,proto3" json:"description,omitempty"` - Enabled *ywrapper.BoolValue `protobuf:"bytes,297236390,opt,name=enabled,proto3" json:"enabled,omitempty"` - Index *ywrapper.UintValue `protobuf:"bytes,279269781,opt,name=index,proto3" json:"index,omitempty"` -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_Config) Reset() { - *x = Interfaces_Interface_Subinterfaces_Subinterface_Config{} - if protoimpl.UnsafeEnabled { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_Config) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Interfaces_Interface_Subinterfaces_Subinterface_Config) ProtoMessage() {} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_Config) ProtoReflect() protoreflect.Message { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[12] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Interfaces_Interface_Subinterfaces_Subinterface_Config.ProtoReflect.Descriptor instead. -func (*Interfaces_Interface_Subinterfaces_Subinterface_Config) Descriptor() ([]byte, []int) { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescGZIP(), []int{0, 0, 3, 0, 0} -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_Config) GetDescription() *ywrapper.StringValue { - if x != nil { - return x.Description - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_Config) GetEnabled() *ywrapper.BoolValue { - if x != nil { - return x.Enabled - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_Config) GetIndex() *ywrapper.UintValue { - if x != nil { - return x.Index - } - return nil -} - -type Interfaces_Interface_Subinterfaces_Subinterface_State struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - AdminStatus Interfaces_Interface_Subinterfaces_Subinterface_State_AdminStatus `protobuf:"varint,250658952,opt,name=admin_status,json=adminStatus,proto3,enum=openconfig.openconfig_interfaces.Interfaces_Interface_Subinterfaces_Subinterface_State_AdminStatus" json:"admin_status,omitempty"` - Counters *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters `protobuf:"bytes,483442783,opt,name=counters,proto3" json:"counters,omitempty"` - Description *ywrapper.StringValue `protobuf:"bytes,49943526,opt,name=description,proto3" json:"description,omitempty"` - Enabled *ywrapper.BoolValue `protobuf:"bytes,468513843,opt,name=enabled,proto3" json:"enabled,omitempty"` - Ifindex *ywrapper.UintValue `protobuf:"bytes,511987815,opt,name=ifindex,proto3" json:"ifindex,omitempty"` - Index *ywrapper.UintValue `protobuf:"bytes,80745756,opt,name=index,proto3" json:"index,omitempty"` - LastChange *ywrapper.UintValue `protobuf:"bytes,29904521,opt,name=last_change,json=lastChange,proto3" json:"last_change,omitempty"` - Logical *ywrapper.BoolValue `protobuf:"bytes,294124401,opt,name=logical,proto3" json:"logical,omitempty"` - Name *ywrapper.StringValue `protobuf:"bytes,279346681,opt,name=name,proto3" json:"name,omitempty"` - OperStatus Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus `protobuf:"varint,401969247,opt,name=oper_status,json=operStatus,proto3,enum=openconfig.openconfig_interfaces.Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus" json:"oper_status,omitempty"` -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State) Reset() { - *x = Interfaces_Interface_Subinterfaces_Subinterface_State{} - if protoimpl.UnsafeEnabled { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Interfaces_Interface_Subinterfaces_Subinterface_State) ProtoMessage() {} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State) ProtoReflect() protoreflect.Message { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[13] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Interfaces_Interface_Subinterfaces_Subinterface_State.ProtoReflect.Descriptor instead. -func (*Interfaces_Interface_Subinterfaces_Subinterface_State) Descriptor() ([]byte, []int) { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescGZIP(), []int{0, 0, 3, 0, 1} -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State) GetAdminStatus() Interfaces_Interface_Subinterfaces_Subinterface_State_AdminStatus { - if x != nil { - return x.AdminStatus - } - return Interfaces_Interface_Subinterfaces_Subinterface_State_ADMINSTATUS_UNSET -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State) GetCounters() *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters { - if x != nil { - return x.Counters - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State) GetDescription() *ywrapper.StringValue { - if x != nil { - return x.Description - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State) GetEnabled() *ywrapper.BoolValue { - if x != nil { - return x.Enabled - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State) GetIfindex() *ywrapper.UintValue { - if x != nil { - return x.Ifindex - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State) GetIndex() *ywrapper.UintValue { - if x != nil { - return x.Index - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State) GetLastChange() *ywrapper.UintValue { - if x != nil { - return x.LastChange - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State) GetLogical() *ywrapper.BoolValue { - if x != nil { - return x.Logical - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State) GetName() *ywrapper.StringValue { - if x != nil { - return x.Name - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State) GetOperStatus() Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus { - if x != nil { - return x.OperStatus - } - return Interfaces_Interface_Subinterfaces_Subinterface_State_OPERSTATUS_UNSET -} - -type Interfaces_Interface_Subinterfaces_Subinterface_State_Counters struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - CarrierTransitions *ywrapper.UintValue `protobuf:"bytes,141120277,opt,name=carrier_transitions,json=carrierTransitions,proto3" json:"carrier_transitions,omitempty"` - InBroadcastPkts *ywrapper.UintValue `protobuf:"bytes,120244022,opt,name=in_broadcast_pkts,json=inBroadcastPkts,proto3" json:"in_broadcast_pkts,omitempty"` - InDiscards *ywrapper.UintValue `protobuf:"bytes,307490461,opt,name=in_discards,json=inDiscards,proto3" json:"in_discards,omitempty"` - InErrors *ywrapper.UintValue `protobuf:"bytes,319720873,opt,name=in_errors,json=inErrors,proto3" json:"in_errors,omitempty"` - InFcsErrors *ywrapper.UintValue `protobuf:"bytes,169858424,opt,name=in_fcs_errors,json=inFcsErrors,proto3" json:"in_fcs_errors,omitempty"` - InMulticastPkts *ywrapper.UintValue `protobuf:"bytes,320618859,opt,name=in_multicast_pkts,json=inMulticastPkts,proto3" json:"in_multicast_pkts,omitempty"` - InOctets *ywrapper.UintValue `protobuf:"bytes,530205868,opt,name=in_octets,json=inOctets,proto3" json:"in_octets,omitempty"` - InPkts *ywrapper.UintValue `protobuf:"bytes,441153352,opt,name=in_pkts,json=inPkts,proto3" json:"in_pkts,omitempty"` - InUnicastPkts *ywrapper.UintValue `protobuf:"bytes,177838880,opt,name=in_unicast_pkts,json=inUnicastPkts,proto3" json:"in_unicast_pkts,omitempty"` - InUnknownProtos *ywrapper.UintValue `protobuf:"bytes,146059814,opt,name=in_unknown_protos,json=inUnknownProtos,proto3" json:"in_unknown_protos,omitempty"` - LastClear *ywrapper.UintValue `protobuf:"bytes,518046966,opt,name=last_clear,json=lastClear,proto3" json:"last_clear,omitempty"` - OutBroadcastPkts *ywrapper.UintValue `protobuf:"bytes,501221245,opt,name=out_broadcast_pkts,json=outBroadcastPkts,proto3" json:"out_broadcast_pkts,omitempty"` - OutDiscards *ywrapper.UintValue `protobuf:"bytes,159539762,opt,name=out_discards,json=outDiscards,proto3" json:"out_discards,omitempty"` - OutErrors *ywrapper.UintValue `protobuf:"bytes,466636898,opt,name=out_errors,json=outErrors,proto3" json:"out_errors,omitempty"` - OutMulticastPkts *ywrapper.UintValue `protobuf:"bytes,326155776,opt,name=out_multicast_pkts,json=outMulticastPkts,proto3" json:"out_multicast_pkts,omitempty"` - OutOctets *ywrapper.UintValue `protobuf:"bytes,50579235,opt,name=out_octets,json=outOctets,proto3" json:"out_octets,omitempty"` - OutPkts *ywrapper.UintValue `protobuf:"bytes,29497115,opt,name=out_pkts,json=outPkts,proto3" json:"out_pkts,omitempty"` - OutUnicastPkts *ywrapper.UintValue `protobuf:"bytes,297910971,opt,name=out_unicast_pkts,json=outUnicastPkts,proto3" json:"out_unicast_pkts,omitempty"` -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) Reset() { - *x = Interfaces_Interface_Subinterfaces_Subinterface_State_Counters{} - if protoimpl.UnsafeEnabled { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[14] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) ProtoMessage() {} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) ProtoReflect() protoreflect.Message { - mi := &file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[14] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Interfaces_Interface_Subinterfaces_Subinterface_State_Counters.ProtoReflect.Descriptor instead. -func (*Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) Descriptor() ([]byte, []int) { - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescGZIP(), []int{0, 0, 3, 0, 1, 0} -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) GetCarrierTransitions() *ywrapper.UintValue { - if x != nil { - return x.CarrierTransitions - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) GetInBroadcastPkts() *ywrapper.UintValue { - if x != nil { - return x.InBroadcastPkts - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) GetInDiscards() *ywrapper.UintValue { - if x != nil { - return x.InDiscards - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) GetInErrors() *ywrapper.UintValue { - if x != nil { - return x.InErrors - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) GetInFcsErrors() *ywrapper.UintValue { - if x != nil { - return x.InFcsErrors - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) GetInMulticastPkts() *ywrapper.UintValue { - if x != nil { - return x.InMulticastPkts - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) GetInOctets() *ywrapper.UintValue { - if x != nil { - return x.InOctets - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) GetInPkts() *ywrapper.UintValue { - if x != nil { - return x.InPkts - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) GetInUnicastPkts() *ywrapper.UintValue { - if x != nil { - return x.InUnicastPkts - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) GetInUnknownProtos() *ywrapper.UintValue { - if x != nil { - return x.InUnknownProtos - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) GetLastClear() *ywrapper.UintValue { - if x != nil { - return x.LastClear - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) GetOutBroadcastPkts() *ywrapper.UintValue { - if x != nil { - return x.OutBroadcastPkts - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) GetOutDiscards() *ywrapper.UintValue { - if x != nil { - return x.OutDiscards - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) GetOutErrors() *ywrapper.UintValue { - if x != nil { - return x.OutErrors - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) GetOutMulticastPkts() *ywrapper.UintValue { - if x != nil { - return x.OutMulticastPkts - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) GetOutOctets() *ywrapper.UintValue { - if x != nil { - return x.OutOctets - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) GetOutPkts() *ywrapper.UintValue { - if x != nil { - return x.OutPkts - } - return nil -} - -func (x *Interfaces_Interface_Subinterfaces_Subinterface_State_Counters) GetOutUnicastPkts() *ywrapper.UintValue { - if x != nil { - return x.OutUnicastPkts - } - return nil -} - -var File_openconfig_openconfig_interfaces_openconfig_interfaces_proto protoreflect.FileDescriptor - -var file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDesc = []byte{ - 0x0a, 0x3c, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x6f, 0x70, 0x65, - 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x73, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x20, - 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, - 0x1a, 0x38, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, - 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x79, 0x67, 0x6f, 0x74, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2f, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2f, 0x79, 0x77, 0x72, 0x61, - 0x70, 0x70, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x30, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x2f, 0x79, 0x67, 0x6f, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x79, 0x65, 0x78, - 0x74, 0x2f, 0x79, 0x65, 0x78, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x6f, 0x70, - 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2f, 0x65, - 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf3, 0x5a, 0x0a, 0x0a, 0x49, - 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x12, 0x75, 0x0a, 0x09, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x18, 0xfa, 0xa7, 0xba, 0xc9, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x39, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x6f, 0x70, - 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x49, - 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x42, 0x18, 0x82, 0x41, 0x15, - 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x52, 0x09, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x1a, 0xd3, 0x58, 0x0a, 0x09, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x12, 0x7a, - 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0xeb, 0xb4, 0xac, 0x9f, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, - 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, - 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x42, 0x1f, 0x82, 0x41, 0x1c, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x83, 0x01, 0x0a, 0x09, 0x68, - 0x6f, 0x6c, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0xd4, 0xfd, 0xf1, 0x53, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x3f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x6f, - 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, - 0x61, 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, - 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2e, 0x48, 0x6f, 0x6c, 0x64, 0x54, 0x69, - 0x6d, 0x65, 0x42, 0x22, 0x82, 0x41, 0x1f, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x68, 0x6f, 0x6c, - 0x64, 0x2d, 0x74, 0x69, 0x6d, 0x65, 0x52, 0x08, 0x68, 0x6f, 0x6c, 0x64, 0x54, 0x69, 0x6d, 0x65, - 0x12, 0x76, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0xac, 0xc6, 0xe6, 0xb8, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x3c, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x42, 0x1e, 0x82, 0x41, 0x1b, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x96, 0x01, 0x0a, 0x0d, 0x73, 0x75, 0x62, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x18, 0x95, 0x9b, 0xa7, 0x9c, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x44, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2e, 0x53, 0x75, 0x62, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x42, 0x26, 0x82, 0x41, 0x23, 0x2f, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x73, 0x52, 0x0d, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x73, 0x1a, 0xc9, 0x04, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x68, 0x0a, 0x0b, - 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0xb4, 0xb3, 0xc9, 0xc7, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, - 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x2b, 0x82, 0x41, - 0x28, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x64, 0x65, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x59, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, - 0x64, 0x18, 0xed, 0xfe, 0xdf, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, - 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, - 0x27, 0x82, 0x41, 0x24, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x2f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, - 0x64, 0x12, 0x6a, 0x0a, 0x0d, 0x6c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x6d, 0x6f, - 0x64, 0x65, 0x18, 0xbb, 0xb4, 0xf1, 0x78, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, - 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x42, 0x2d, 0x82, 0x41, 0x2a, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, - 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x2f, 0x6c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, 0x2d, 0x6d, 0x6f, 0x64, 0x65, 0x52, - 0x0c, 0x6c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x4e, 0x0a, - 0x03, 0x6d, 0x74, 0x75, 0x18, 0xa6, 0x87, 0xb2, 0xb3, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, - 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x42, 0x23, 0x82, 0x41, 0x20, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x63, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x6d, 0x74, 0x75, 0x52, 0x03, 0x6d, 0x74, 0x75, 0x12, 0x52, 0x0a, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x9b, 0xf0, 0xd9, 0x18, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, - 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x24, 0x82, 0x41, 0x21, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, - 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x52, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x12, 0x6a, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x9e, 0xbf, 0xf9, 0x44, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x2d, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, - 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x49, 0x45, 0x54, 0x46, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, - 0x61, 0x63, 0x65, 0x73, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x54, 0x79, 0x70, - 0x65, 0x42, 0x24, 0x82, 0x41, 0x21, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x1a, 0x9d, 0x05, - 0x0a, 0x08, 0x48, 0x6f, 0x6c, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x8d, 0x01, 0x0a, 0x06, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0xd9, 0xb3, 0xf6, 0x96, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x46, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x6f, 0x70, 0x65, - 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, - 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2e, 0x48, 0x6f, 0x6c, 0x64, 0x54, 0x69, 0x6d, 0x65, - 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x29, 0x82, 0x41, 0x26, 0x2f, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x2f, 0x68, 0x6f, 0x6c, 0x64, 0x2d, 0x74, 0x69, 0x6d, 0x65, 0x2f, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x89, 0x01, 0x0a, 0x05, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x18, 0xae, 0xd3, 0xa8, 0xe6, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x45, - 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x6f, 0x70, 0x65, 0x6e, - 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2e, 0x48, 0x6f, 0x6c, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x2e, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x42, 0x28, 0x82, 0x41, 0x25, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, - 0x68, 0x6f, 0x6c, 0x64, 0x2d, 0x74, 0x69, 0x6d, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x52, - 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x1a, 0xba, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x12, 0x5a, 0x0a, 0x04, 0x64, 0x6f, 0x77, 0x6e, 0x18, 0xd8, 0x8c, 0xd0, 0x51, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, - 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x2e, 0x82, 0x41, 0x2b, 0x2f, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x2f, 0x68, 0x6f, 0x6c, 0x64, 0x2d, 0x74, 0x69, 0x6d, 0x65, 0x2f, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x2f, 0x64, 0x6f, 0x77, 0x6e, 0x52, 0x04, 0x64, 0x6f, 0x77, 0x6e, 0x12, 0x54, 0x0a, - 0x02, 0x75, 0x70, 0x18, 0xfb, 0xe3, 0xc9, 0x1d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, - 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x42, 0x2c, 0x82, 0x41, 0x29, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x68, 0x6f, 0x6c, 0x64, - 0x2d, 0x74, 0x69, 0x6d, 0x65, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x75, 0x70, 0x52, - 0x02, 0x75, 0x70, 0x1a, 0xb7, 0x01, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x59, 0x0a, - 0x04, 0x64, 0x6f, 0x77, 0x6e, 0x18, 0xe9, 0x86, 0x87, 0x50, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, - 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x42, 0x2d, 0x82, 0x41, 0x2a, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x68, 0x6f, - 0x6c, 0x64, 0x2d, 0x74, 0x69, 0x6d, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x64, 0x6f, - 0x77, 0x6e, 0x52, 0x04, 0x64, 0x6f, 0x77, 0x6e, 0x12, 0x53, 0x0a, 0x02, 0x75, 0x70, 0x18, 0xae, - 0xc9, 0xde, 0x6a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, - 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x2b, 0x82, 0x41, - 0x28, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x68, 0x6f, 0x6c, 0x64, 0x2d, 0x74, 0x69, 0x6d, 0x65, - 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x75, 0x70, 0x52, 0x02, 0x75, 0x70, 0x1a, 0x9b, 0x1e, - 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x9c, 0x01, 0x0a, 0x0c, 0x61, 0x64, 0x6d, 0x69, - 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0xab, 0xee, 0xa0, 0xe2, 0x01, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x48, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, - 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, - 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x2e, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x2b, 0x82, 0x41, - 0x28, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x61, 0x64, 0x6d, - 0x69, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x0b, 0x61, 0x64, 0x6d, 0x69, 0x6e, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x8d, 0x01, 0x0a, 0x08, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x65, 0x72, 0x73, 0x18, 0x8c, 0xac, 0xf1, 0x27, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x45, 0x2e, 0x6f, - 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, - 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, - 0x65, 0x72, 0x73, 0x42, 0x27, 0x82, 0x41, 0x24, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x52, 0x08, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x12, 0x67, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x97, 0x9f, 0xd9, 0xb9, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x15, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, - 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x2a, 0x82, 0x41, 0x27, 0x2f, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x59, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x9e, 0x9b, 0xe6, 0x9d, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, - 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x26, 0x82, 0x41, 0x23, 0x2f, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, - 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, - 0x64, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x58, 0x0a, 0x07, 0x69, 0x66, - 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0xaa, 0xd7, 0xae, 0x37, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, - 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x42, 0x26, 0x82, 0x41, 0x23, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x2f, 0x69, 0x66, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x07, 0x69, 0x66, 0x69, - 0x6e, 0x64, 0x65, 0x78, 0x12, 0x63, 0x0a, 0x0b, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x63, 0x68, 0x61, - 0x6e, 0x67, 0x65, 0x18, 0x90, 0xe1, 0xdc, 0x3c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, - 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x42, 0x2a, 0x82, 0x41, 0x27, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x2f, 0x6c, 0x61, 0x73, 0x74, 0x2d, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x0a, 0x6c, - 0x61, 0x73, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x59, 0x0a, 0x07, 0x6c, 0x6f, 0x67, - 0x69, 0x63, 0x61, 0x6c, 0x18, 0xb8, 0xc7, 0x83, 0xd2, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, - 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x42, 0x26, 0x82, 0x41, 0x23, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x2f, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x52, 0x07, 0x6c, 0x6f, 0x67, - 0x69, 0x63, 0x61, 0x6c, 0x12, 0x6a, 0x0a, 0x0d, 0x6c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, - 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0xd8, 0x96, 0xea, 0xb1, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x42, 0x2c, 0x82, 0x41, 0x29, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, - 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x2f, 0x6c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, 0x2d, 0x6d, 0x6f, - 0x64, 0x65, 0x52, 0x0c, 0x6c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, 0x4d, 0x6f, 0x64, 0x65, - 0x12, 0x4c, 0x0a, 0x03, 0x6d, 0x74, 0x75, 0x18, 0xd5, 0x9a, 0xfb, 0x2d, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x22, 0x82, 0x41, 0x1f, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x6d, 0x74, 0x75, 0x52, 0x03, 0x6d, 0x74, 0x75, 0x12, 0x52, - 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0xee, 0xf4, 0x8a, 0xf0, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x15, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x72, 0x69, - 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x23, 0x82, 0x41, 0x20, 0x2f, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0x98, 0x01, 0x0a, 0x0b, 0x6f, 0x70, 0x65, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x18, 0xf2, 0xca, 0xa6, 0xe0, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x47, 0x2e, 0x6f, - 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, - 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x2a, 0x82, 0x41, 0x27, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x6f, 0x70, 0x65, 0x72, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x52, 0x0a, 0x6f, 0x70, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x6a, 0x0a, - 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0xe3, 0xd3, 0xe3, 0xaa, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x2d, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x65, 0x6e, 0x75, - 0x6d, 0x73, 0x2e, 0x49, 0x45, 0x54, 0x46, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x73, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x42, 0x23, - 0x82, 0x41, 0x20, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x74, - 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x1a, 0xbe, 0x10, 0x0a, 0x08, 0x43, 0x6f, - 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x12, 0x85, 0x01, 0x0a, 0x13, 0x63, 0x61, 0x72, 0x72, 0x69, - 0x65, 0x72, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xba, - 0xc1, 0x90, 0x81, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, - 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x3b, 0x82, - 0x41, 0x38, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x63, 0x61, 0x72, 0x72, 0x69, 0x65, 0x72, 0x2d, 0x74, - 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x12, 0x63, 0x61, 0x72, 0x72, - 0x69, 0x65, 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x7e, - 0x0a, 0x11, 0x69, 0x6e, 0x5f, 0x62, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x5f, 0x70, - 0x6b, 0x74, 0x73, 0x18, 0x85, 0x96, 0xce, 0x85, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, - 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x42, 0x39, 0x82, 0x41, 0x36, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x69, 0x6e, 0x2d, 0x62, - 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x2d, 0x70, 0x6b, 0x74, 0x73, 0x52, 0x0f, 0x69, - 0x6e, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x50, 0x6b, 0x74, 0x73, 0x12, 0x6c, - 0x0a, 0x0b, 0x69, 0x6e, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x73, 0x18, 0xfa, 0x95, - 0xdb, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, - 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x33, 0x82, 0x41, 0x30, - 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x65, 0x72, 0x73, 0x2f, 0x69, 0x6e, 0x2d, 0x64, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x73, - 0x52, 0x0a, 0x69, 0x6e, 0x44, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x73, 0x12, 0x67, 0x0a, 0x09, - 0x69, 0x6e, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0xea, 0xcd, 0xe2, 0xd9, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, - 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x31, 0x82, 0x41, 0x2e, 0x2f, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, - 0x73, 0x2f, 0x69, 0x6e, 0x2d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x52, 0x08, 0x69, 0x6e, 0x45, - 0x72, 0x72, 0x6f, 0x72, 0x73, 0x12, 0x72, 0x0a, 0x0d, 0x69, 0x6e, 0x5f, 0x66, 0x63, 0x73, 0x5f, - 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0xf3, 0xdd, 0x94, 0xef, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x35, 0x82, 0x41, 0x32, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x69, - 0x6e, 0x2d, 0x66, 0x63, 0x73, 0x2d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x52, 0x0b, 0x69, 0x6e, - 0x46, 0x63, 0x73, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x12, 0x7d, 0x0a, 0x11, 0x69, 0x6e, 0x5f, - 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x6b, 0x74, 0x73, 0x18, 0x88, - 0xb3, 0x81, 0x36, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, - 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x39, 0x82, 0x41, - 0x36, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x69, 0x6e, 0x2d, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x61, - 0x73, 0x74, 0x2d, 0x70, 0x6b, 0x74, 0x73, 0x52, 0x0f, 0x69, 0x6e, 0x4d, 0x75, 0x6c, 0x74, 0x69, - 0x63, 0x61, 0x73, 0x74, 0x50, 0x6b, 0x74, 0x73, 0x12, 0x67, 0x0a, 0x09, 0x69, 0x6e, 0x5f, 0x6f, - 0x63, 0x74, 0x65, 0x74, 0x73, 0x18, 0xcb, 0x97, 0xed, 0x9e, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x42, 0x31, 0x82, 0x41, 0x2e, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, - 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x69, 0x6e, - 0x2d, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x73, 0x52, 0x08, 0x69, 0x6e, 0x4f, 0x63, 0x74, 0x65, 0x74, - 0x73, 0x12, 0x61, 0x0a, 0x07, 0x69, 0x6e, 0x5f, 0x70, 0x6b, 0x74, 0x73, 0x18, 0xe3, 0xfb, 0xed, - 0xc4, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, - 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x2f, 0x82, 0x41, 0x2c, - 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x65, 0x72, 0x73, 0x2f, 0x69, 0x6e, 0x2d, 0x70, 0x6b, 0x74, 0x73, 0x52, 0x06, 0x69, 0x6e, - 0x50, 0x6b, 0x74, 0x73, 0x12, 0x78, 0x0a, 0x0f, 0x69, 0x6e, 0x5f, 0x75, 0x6e, 0x69, 0x63, 0x61, - 0x73, 0x74, 0x5f, 0x70, 0x6b, 0x74, 0x73, 0x18, 0xf3, 0xf5, 0x89, 0x82, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, - 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x37, 0x82, 0x41, 0x34, 0x2f, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x2f, - 0x69, 0x6e, 0x2d, 0x75, 0x6e, 0x69, 0x63, 0x61, 0x73, 0x74, 0x2d, 0x70, 0x6b, 0x74, 0x73, 0x52, - 0x0d, 0x69, 0x6e, 0x55, 0x6e, 0x69, 0x63, 0x61, 0x73, 0x74, 0x50, 0x6b, 0x74, 0x73, 0x12, 0x7d, - 0x0a, 0x11, 0x69, 0x6e, 0x5f, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x5f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x73, 0x18, 0xa9, 0xbf, 0x92, 0x73, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, - 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x42, 0x39, 0x82, 0x41, 0x36, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x69, 0x6e, 0x2d, 0x75, 0x6e, - 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x2d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x52, 0x0f, 0x69, 0x6e, - 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x12, 0x69, 0x0a, - 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x18, 0xc7, 0xb9, 0xd9, 0x58, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, - 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x32, 0x82, 0x41, 0x2f, 0x2f, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, - 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, - 0x72, 0x73, 0x2f, 0x6c, 0x61, 0x73, 0x74, 0x2d, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x52, 0x09, 0x6c, - 0x61, 0x73, 0x74, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x12, 0x81, 0x01, 0x0a, 0x12, 0x6f, 0x75, 0x74, - 0x5f, 0x62, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x6b, 0x74, 0x73, 0x18, - 0xe4, 0xef, 0xb9, 0xa1, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, - 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x3a, - 0x82, 0x41, 0x37, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x6f, 0x75, 0x74, 0x2d, 0x62, 0x72, 0x6f, 0x61, - 0x64, 0x63, 0x61, 0x73, 0x74, 0x2d, 0x70, 0x6b, 0x74, 0x73, 0x52, 0x10, 0x6f, 0x75, 0x74, 0x42, - 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x50, 0x6b, 0x74, 0x73, 0x12, 0x6f, 0x0a, 0x0c, - 0x6f, 0x75, 0x74, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x73, 0x18, 0xc7, 0xa5, 0x92, - 0x79, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, - 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x34, 0x82, 0x41, 0x31, 0x2f, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x65, 0x72, 0x73, 0x2f, 0x6f, 0x75, 0x74, 0x2d, 0x64, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x73, - 0x52, 0x0b, 0x6f, 0x75, 0x74, 0x44, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x73, 0x12, 0x6a, 0x0a, - 0x0a, 0x6f, 0x75, 0x74, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0xc7, 0xec, 0xd1, 0xe0, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, - 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x32, 0x82, 0x41, 0x2f, 0x2f, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x65, 0x72, 0x73, 0x2f, 0x6f, 0x75, 0x74, 0x2d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x52, 0x09, - 0x6f, 0x75, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x12, 0x81, 0x01, 0x0a, 0x12, 0x6f, 0x75, - 0x74, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x6b, 0x74, 0x73, - 0x18, 0xf5, 0xb0, 0xa8, 0xda, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, - 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, - 0x3a, 0x82, 0x41, 0x37, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x6f, 0x75, 0x74, 0x2d, 0x6d, 0x75, 0x6c, - 0x74, 0x69, 0x63, 0x61, 0x73, 0x74, 0x2d, 0x70, 0x6b, 0x74, 0x73, 0x52, 0x10, 0x6f, 0x75, 0x74, - 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x61, 0x73, 0x74, 0x50, 0x6b, 0x74, 0x73, 0x12, 0x69, 0x0a, - 0x0a, 0x6f, 0x75, 0x74, 0x5f, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x73, 0x18, 0xca, 0xb3, 0xec, 0x5f, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, - 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x32, 0x82, 0x41, 0x2f, 0x2f, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, - 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, - 0x72, 0x73, 0x2f, 0x6f, 0x75, 0x74, 0x2d, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x73, 0x52, 0x09, 0x6f, - 0x75, 0x74, 0x4f, 0x63, 0x74, 0x65, 0x74, 0x73, 0x12, 0x64, 0x0a, 0x08, 0x6f, 0x75, 0x74, 0x5f, - 0x70, 0x6b, 0x74, 0x73, 0x18, 0x8a, 0xf2, 0xd3, 0xd0, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, - 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x42, 0x30, 0x82, 0x41, 0x2d, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x6f, 0x75, 0x74, - 0x2d, 0x70, 0x6b, 0x74, 0x73, 0x52, 0x07, 0x6f, 0x75, 0x74, 0x50, 0x6b, 0x74, 0x73, 0x12, 0x7a, - 0x0a, 0x10, 0x6f, 0x75, 0x74, 0x5f, 0x75, 0x6e, 0x69, 0x63, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x6b, - 0x74, 0x73, 0x18, 0xa6, 0xae, 0xb6, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, - 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x42, 0x38, 0x82, 0x41, 0x35, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, - 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x6f, 0x75, 0x74, 0x2d, 0x75, 0x6e, - 0x69, 0x63, 0x61, 0x73, 0x74, 0x2d, 0x70, 0x6b, 0x74, 0x73, 0x52, 0x0e, 0x6f, 0x75, 0x74, 0x55, - 0x6e, 0x69, 0x63, 0x61, 0x73, 0x74, 0x50, 0x6b, 0x74, 0x73, 0x22, 0x83, 0x01, 0x0a, 0x0b, 0x41, - 0x64, 0x6d, 0x69, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x15, 0x0a, 0x11, 0x41, 0x44, - 0x4d, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x45, 0x54, 0x10, - 0x00, 0x12, 0x19, 0x0a, 0x0e, 0x41, 0x44, 0x4d, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, - 0x5f, 0x55, 0x50, 0x10, 0x01, 0x1a, 0x05, 0x82, 0x41, 0x02, 0x55, 0x50, 0x12, 0x1d, 0x0a, 0x10, - 0x41, 0x44, 0x4d, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x44, 0x4f, 0x57, 0x4e, - 0x10, 0x02, 0x1a, 0x07, 0x82, 0x41, 0x04, 0x44, 0x4f, 0x57, 0x4e, 0x12, 0x23, 0x0a, 0x13, 0x41, - 0x44, 0x4d, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x54, 0x45, 0x53, 0x54, 0x49, - 0x4e, 0x47, 0x10, 0x03, 0x1a, 0x0a, 0x82, 0x41, 0x07, 0x54, 0x45, 0x53, 0x54, 0x49, 0x4e, 0x47, - 0x22, 0xa8, 0x02, 0x0a, 0x0a, 0x4f, 0x70, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, - 0x14, 0x0a, 0x10, 0x4f, 0x50, 0x45, 0x52, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, - 0x53, 0x45, 0x54, 0x10, 0x00, 0x12, 0x18, 0x0a, 0x0d, 0x4f, 0x50, 0x45, 0x52, 0x53, 0x54, 0x41, - 0x54, 0x55, 0x53, 0x5f, 0x55, 0x50, 0x10, 0x02, 0x1a, 0x05, 0x82, 0x41, 0x02, 0x55, 0x50, 0x12, - 0x1c, 0x0a, 0x0f, 0x4f, 0x50, 0x45, 0x52, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x44, 0x4f, - 0x57, 0x4e, 0x10, 0x03, 0x1a, 0x07, 0x82, 0x41, 0x04, 0x44, 0x4f, 0x57, 0x4e, 0x12, 0x22, 0x0a, - 0x12, 0x4f, 0x50, 0x45, 0x52, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x54, 0x45, 0x53, 0x54, - 0x49, 0x4e, 0x47, 0x10, 0x04, 0x1a, 0x0a, 0x82, 0x41, 0x07, 0x54, 0x45, 0x53, 0x54, 0x49, 0x4e, - 0x47, 0x12, 0x22, 0x0a, 0x12, 0x4f, 0x50, 0x45, 0x52, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, - 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x05, 0x1a, 0x0a, 0x82, 0x41, 0x07, 0x55, 0x4e, - 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x12, 0x22, 0x0a, 0x12, 0x4f, 0x50, 0x45, 0x52, 0x53, 0x54, 0x41, - 0x54, 0x55, 0x53, 0x5f, 0x44, 0x4f, 0x52, 0x4d, 0x41, 0x4e, 0x54, 0x10, 0x06, 0x1a, 0x0a, 0x82, - 0x41, 0x07, 0x44, 0x4f, 0x52, 0x4d, 0x41, 0x4e, 0x54, 0x12, 0x2a, 0x0a, 0x16, 0x4f, 0x50, 0x45, - 0x52, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x50, 0x52, 0x45, 0x53, - 0x45, 0x4e, 0x54, 0x10, 0x07, 0x1a, 0x0e, 0x82, 0x41, 0x0b, 0x4e, 0x4f, 0x54, 0x5f, 0x50, 0x52, - 0x45, 0x53, 0x45, 0x4e, 0x54, 0x12, 0x34, 0x0a, 0x1b, 0x4f, 0x50, 0x45, 0x52, 0x53, 0x54, 0x41, - 0x54, 0x55, 0x53, 0x5f, 0x4c, 0x4f, 0x57, 0x45, 0x52, 0x5f, 0x4c, 0x41, 0x59, 0x45, 0x52, 0x5f, - 0x44, 0x4f, 0x57, 0x4e, 0x10, 0x08, 0x1a, 0x13, 0x82, 0x41, 0x10, 0x4c, 0x4f, 0x57, 0x45, 0x52, - 0x5f, 0x4c, 0x41, 0x59, 0x45, 0x52, 0x5f, 0x44, 0x4f, 0x57, 0x4e, 0x1a, 0xa8, 0x2c, 0x0a, 0x0d, - 0x53, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x12, 0xb1, 0x01, - 0x0a, 0x0c, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x18, 0x83, - 0xa8, 0xd1, 0xdd, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x54, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x2e, 0x53, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x53, - 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x42, 0x33, - 0x82, 0x41, 0x30, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, - 0x61, 0x63, 0x65, 0x52, 0x0c, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x1a, 0x86, 0x29, 0x0a, 0x0c, 0x53, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x12, 0xaf, 0x01, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x84, 0x9f, - 0xb9, 0x53, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x58, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, - 0x61, 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2e, 0x53, - 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x53, 0x75, 0x62, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x42, 0x3a, 0x82, 0x41, 0x37, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, - 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x63, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x12, 0xac, 0x01, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x9d, - 0x89, 0xae, 0xef, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x57, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x2e, 0x53, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x53, - 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x42, 0x39, 0x82, 0x41, 0x36, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x1a, 0xf6, 0x02, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x83, - 0x01, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0xdf, - 0xe7, 0xea, 0x85, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, - 0x70, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, - 0x46, 0x82, 0x41, 0x43, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x64, 0x65, 0x73, 0x63, - 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x75, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, - 0xa6, 0xef, 0xdd, 0x8d, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, - 0x70, 0x70, 0x65, 0x72, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x42, - 0x82, 0x41, 0x3f, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, - 0x61, 0x63, 0x65, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x65, 0x6e, 0x61, 0x62, 0x6c, - 0x65, 0x64, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x6f, 0x0a, 0x05, 0x69, - 0x6e, 0x64, 0x65, 0x78, 0x18, 0x95, 0xa3, 0x95, 0x85, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, - 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x42, 0x40, 0x82, 0x41, 0x3d, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, - 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, - 0x69, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x1a, 0x9b, 0x23, 0x0a, - 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0xd1, 0x01, 0x0a, 0x0c, 0x61, 0x64, 0x6d, 0x69, 0x6e, - 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x88, 0x81, 0xc3, 0x77, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x63, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x6f, 0x70, - 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x49, - 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2e, 0x53, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x53, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, - 0x61, 0x63, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x46, 0x82, 0x41, 0x43, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, - 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, - 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x2f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x0b, 0x61, - 0x64, 0x6d, 0x69, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0xc4, 0x01, 0x0a, 0x08, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x18, 0xdf, 0x80, 0xc3, 0xe6, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x60, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x6f, - 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, - 0x61, 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, - 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2e, 0x53, 0x75, 0x62, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x53, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, - 0x65, 0x72, 0x73, 0x42, 0x42, 0x82, 0x41, 0x3f, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, - 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x52, 0x08, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, - 0x73, 0x12, 0x81, 0x01, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0xe6, 0xa7, 0xe8, 0x17, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x79, 0x77, 0x72, - 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x42, 0x45, 0x82, 0x41, 0x42, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x64, 0x65, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x74, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, - 0x18, 0xb3, 0xe8, 0xb3, 0xdf, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, - 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, - 0x41, 0x82, 0x41, 0x3e, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x65, 0x6e, 0x61, 0x62, 0x6c, - 0x65, 0x64, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x74, 0x0a, 0x07, 0x69, - 0x66, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0xe7, 0xa0, 0x91, 0xf4, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x41, 0x82, 0x41, 0x3e, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, - 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, - 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x2f, 0x69, 0x66, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x07, 0x69, 0x66, 0x69, 0x6e, 0x64, 0x65, - 0x78, 0x12, 0x6d, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x9c, 0xaa, 0xc0, 0x26, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, - 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x3f, 0x82, 0x41, 0x3c, 0x2f, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, - 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, - 0x12, 0x7e, 0x0a, 0x0b, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x18, - 0x89, 0x9d, 0xa1, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, - 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x45, 0x82, - 0x41, 0x42, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x6c, 0x61, 0x73, 0x74, 0x2d, 0x63, 0x68, - 0x61, 0x6e, 0x67, 0x65, 0x52, 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, - 0x12, 0x74, 0x0a, 0x07, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x18, 0xf1, 0xf6, 0x9f, 0x8c, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, - 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x41, 0x82, 0x41, 0x3e, 0x2f, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x52, 0x07, 0x6c, - 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x12, 0x6d, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0xf9, - 0xfb, 0x99, 0x85, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, - 0x70, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, - 0x3e, 0x82, 0x41, 0x3b, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x52, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0xce, 0x01, 0x0a, 0x0b, 0x6f, 0x70, 0x65, 0x72, 0x5f, 0x73, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0xdf, 0xa0, 0xd6, 0xbf, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x62, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x6f, 0x70, 0x65, - 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, - 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2e, 0x53, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x53, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x42, 0x45, 0x82, 0x41, 0x42, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, - 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x6f, - 0x70, 0x65, 0x72, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x0a, 0x6f, 0x70, 0x65, 0x72, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x1a, 0xb0, 0x14, 0x0a, 0x08, 0x43, 0x6f, 0x75, 0x6e, 0x74, - 0x65, 0x72, 0x73, 0x12, 0x9f, 0x01, 0x0a, 0x13, 0x63, 0x61, 0x72, 0x72, 0x69, 0x65, 0x72, 0x5f, - 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x95, 0xa6, 0xa5, 0x43, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, - 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x56, 0x82, 0x41, 0x53, 0x2f, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, - 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x63, 0x61, - 0x72, 0x72, 0x69, 0x65, 0x72, 0x2d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x52, 0x12, 0x63, 0x61, 0x72, 0x72, 0x69, 0x65, 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x98, 0x01, 0x0a, 0x11, 0x69, 0x6e, 0x5f, 0x62, 0x72, 0x6f, - 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x6b, 0x74, 0x73, 0x18, 0xb6, 0x8e, 0xab, 0x39, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, - 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x54, 0x82, 0x41, 0x51, 0x2f, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, - 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x69, 0x6e, - 0x2d, 0x62, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x2d, 0x70, 0x6b, 0x74, 0x73, 0x52, - 0x0f, 0x69, 0x6e, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x50, 0x6b, 0x74, 0x73, - 0x12, 0x88, 0x01, 0x0a, 0x0b, 0x69, 0x6e, 0x5f, 0x64, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x73, - 0x18, 0x9d, 0xdd, 0xcf, 0x92, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, - 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, - 0x4e, 0x82, 0x41, 0x4b, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x65, 0x72, 0x73, 0x2f, 0x69, 0x6e, 0x2d, 0x64, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x73, 0x52, - 0x0a, 0x69, 0x6e, 0x44, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x73, 0x12, 0x82, 0x01, 0x0a, 0x09, - 0x69, 0x6e, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0xa9, 0x9b, 0xba, 0x98, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, - 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x4c, 0x82, 0x41, 0x49, 0x2f, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, - 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x69, 0x6e, 0x2d, - 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x52, 0x08, 0x69, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, - 0x12, 0x8c, 0x01, 0x0a, 0x0d, 0x69, 0x6e, 0x5f, 0x66, 0x63, 0x73, 0x5f, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x73, 0x18, 0xf8, 0xaa, 0xff, 0x50, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, - 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x42, 0x50, 0x82, 0x41, 0x4d, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, - 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x65, 0x72, 0x73, 0x2f, 0x69, 0x6e, 0x2d, 0x66, 0x63, 0x73, 0x2d, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x73, 0x52, 0x0b, 0x69, 0x6e, 0x46, 0x63, 0x73, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x12, - 0x99, 0x01, 0x0a, 0x11, 0x69, 0x6e, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x61, 0x73, 0x74, - 0x5f, 0x70, 0x6b, 0x74, 0x73, 0x18, 0xeb, 0x82, 0xf1, 0x98, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x42, 0x54, 0x82, 0x41, 0x51, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, - 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, - 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x69, 0x6e, 0x2d, 0x6d, 0x75, 0x6c, 0x74, - 0x69, 0x63, 0x61, 0x73, 0x74, 0x2d, 0x70, 0x6b, 0x74, 0x73, 0x52, 0x0f, 0x69, 0x6e, 0x4d, 0x75, - 0x6c, 0x74, 0x69, 0x63, 0x61, 0x73, 0x74, 0x50, 0x6b, 0x74, 0x73, 0x12, 0x82, 0x01, 0x0a, 0x09, - 0x69, 0x6e, 0x5f, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x73, 0x18, 0xac, 0x99, 0xe9, 0xfc, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, - 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x4c, 0x82, 0x41, 0x49, 0x2f, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, - 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x69, 0x6e, 0x2d, - 0x6f, 0x63, 0x74, 0x65, 0x74, 0x73, 0x52, 0x08, 0x69, 0x6e, 0x4f, 0x63, 0x74, 0x65, 0x74, 0x73, - 0x12, 0x7c, 0x0a, 0x07, 0x69, 0x6e, 0x5f, 0x70, 0x6b, 0x74, 0x73, 0x18, 0xc8, 0xee, 0xad, 0xd2, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, - 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x4a, 0x82, 0x41, 0x47, 0x2f, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x69, - 0x6e, 0x2d, 0x70, 0x6b, 0x74, 0x73, 0x52, 0x06, 0x69, 0x6e, 0x50, 0x6b, 0x74, 0x73, 0x12, 0x92, - 0x01, 0x0a, 0x0f, 0x69, 0x6e, 0x5f, 0x75, 0x6e, 0x69, 0x63, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x6b, - 0x74, 0x73, 0x18, 0xa0, 0xb6, 0xe6, 0x54, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, - 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x42, 0x52, 0x82, 0x41, 0x4f, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, - 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x65, 0x72, 0x73, 0x2f, 0x69, 0x6e, 0x2d, 0x75, 0x6e, 0x69, 0x63, 0x61, 0x73, 0x74, 0x2d, - 0x70, 0x6b, 0x74, 0x73, 0x52, 0x0d, 0x69, 0x6e, 0x55, 0x6e, 0x69, 0x63, 0x61, 0x73, 0x74, 0x50, - 0x6b, 0x74, 0x73, 0x12, 0x98, 0x01, 0x0a, 0x11, 0x69, 0x6e, 0x5f, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, - 0x77, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x18, 0xa6, 0xe4, 0xd2, 0x45, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, - 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x54, 0x82, 0x41, 0x51, 0x2f, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, - 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x69, 0x6e, 0x2d, 0x75, - 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x2d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x52, 0x0f, 0x69, - 0x6e, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x12, 0x85, - 0x01, 0x0a, 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x18, 0xf6, 0x89, - 0x83, 0xf7, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, - 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x4d, 0x82, 0x41, - 0x4a, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, - 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, - 0x2f, 0x6c, 0x61, 0x73, 0x74, 0x2d, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x52, 0x09, 0x6c, 0x61, 0x73, - 0x74, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x12, 0x9c, 0x01, 0x0a, 0x12, 0x6f, 0x75, 0x74, 0x5f, 0x62, - 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x6b, 0x74, 0x73, 0x18, 0xfd, 0x8e, - 0x80, 0xef, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, - 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x55, 0x82, 0x41, - 0x52, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, - 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, - 0x2f, 0x6f, 0x75, 0x74, 0x2d, 0x62, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x2d, 0x70, - 0x6b, 0x74, 0x73, 0x52, 0x10, 0x6f, 0x75, 0x74, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, - 0x74, 0x50, 0x6b, 0x74, 0x73, 0x12, 0x8a, 0x01, 0x0a, 0x0c, 0x6f, 0x75, 0x74, 0x5f, 0x64, 0x69, - 0x73, 0x63, 0x61, 0x72, 0x64, 0x73, 0x18, 0xb2, 0xc4, 0x89, 0x4c, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x42, 0x4f, 0x82, 0x41, 0x4c, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, - 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, - 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x6f, 0x75, 0x74, 0x2d, 0x64, 0x69, 0x73, - 0x63, 0x61, 0x72, 0x64, 0x73, 0x52, 0x0b, 0x6f, 0x75, 0x74, 0x44, 0x69, 0x73, 0x63, 0x61, 0x72, - 0x64, 0x73, 0x12, 0x85, 0x01, 0x0a, 0x0a, 0x6f, 0x75, 0x74, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x73, 0x18, 0xe2, 0xa0, 0xc1, 0xde, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, - 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x42, 0x4d, 0x82, 0x41, 0x4a, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, - 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x65, 0x72, 0x73, 0x2f, 0x6f, 0x75, 0x74, 0x2d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x52, - 0x09, 0x6f, 0x75, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x12, 0x9c, 0x01, 0x0a, 0x12, 0x6f, - 0x75, 0x74, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x6b, 0x74, - 0x73, 0x18, 0x80, 0xfc, 0xc2, 0x9b, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, - 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x42, 0x55, 0x82, 0x41, 0x52, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, - 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x65, 0x72, 0x73, 0x2f, 0x6f, 0x75, 0x74, 0x2d, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x61, - 0x73, 0x74, 0x2d, 0x70, 0x6b, 0x74, 0x73, 0x52, 0x10, 0x6f, 0x75, 0x74, 0x4d, 0x75, 0x6c, 0x74, - 0x69, 0x63, 0x61, 0x73, 0x74, 0x50, 0x6b, 0x74, 0x73, 0x12, 0x84, 0x01, 0x0a, 0x0a, 0x6f, 0x75, - 0x74, 0x5f, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x73, 0x18, 0xa3, 0x8e, 0x8f, 0x18, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, - 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x4d, 0x82, 0x41, 0x4a, 0x2f, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, - 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x6f, 0x75, 0x74, 0x2d, 0x6f, - 0x63, 0x74, 0x65, 0x74, 0x73, 0x52, 0x09, 0x6f, 0x75, 0x74, 0x4f, 0x63, 0x74, 0x65, 0x74, 0x73, - 0x12, 0x7e, 0x0a, 0x08, 0x6f, 0x75, 0x74, 0x5f, 0x70, 0x6b, 0x74, 0x73, 0x18, 0x9b, 0xae, 0x88, - 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, - 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x4b, 0x82, 0x41, 0x48, 0x2f, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x6f, - 0x75, 0x74, 0x2d, 0x70, 0x6b, 0x74, 0x73, 0x52, 0x07, 0x6f, 0x75, 0x74, 0x50, 0x6b, 0x74, 0x73, - 0x12, 0x96, 0x01, 0x0a, 0x10, 0x6f, 0x75, 0x74, 0x5f, 0x75, 0x6e, 0x69, 0x63, 0x61, 0x73, 0x74, - 0x5f, 0x70, 0x6b, 0x74, 0x73, 0x18, 0xbb, 0x85, 0x87, 0x8e, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x13, 0x2e, 0x79, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2e, 0x55, 0x69, 0x6e, 0x74, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x42, 0x53, 0x82, 0x41, 0x50, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, - 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, - 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x2f, 0x6f, 0x75, 0x74, 0x2d, 0x75, 0x6e, 0x69, - 0x63, 0x61, 0x73, 0x74, 0x2d, 0x70, 0x6b, 0x74, 0x73, 0x52, 0x0e, 0x6f, 0x75, 0x74, 0x55, 0x6e, - 0x69, 0x63, 0x61, 0x73, 0x74, 0x50, 0x6b, 0x74, 0x73, 0x22, 0x83, 0x01, 0x0a, 0x0b, 0x41, 0x64, - 0x6d, 0x69, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x15, 0x0a, 0x11, 0x41, 0x44, 0x4d, - 0x49, 0x4e, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x45, 0x54, 0x10, 0x00, - 0x12, 0x19, 0x0a, 0x0e, 0x41, 0x44, 0x4d, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, - 0x55, 0x50, 0x10, 0x01, 0x1a, 0x05, 0x82, 0x41, 0x02, 0x55, 0x50, 0x12, 0x1d, 0x0a, 0x10, 0x41, - 0x44, 0x4d, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x44, 0x4f, 0x57, 0x4e, 0x10, - 0x02, 0x1a, 0x07, 0x82, 0x41, 0x04, 0x44, 0x4f, 0x57, 0x4e, 0x12, 0x23, 0x0a, 0x13, 0x41, 0x44, - 0x4d, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x54, 0x45, 0x53, 0x54, 0x49, 0x4e, - 0x47, 0x10, 0x03, 0x1a, 0x0a, 0x82, 0x41, 0x07, 0x54, 0x45, 0x53, 0x54, 0x49, 0x4e, 0x47, 0x22, - 0xa8, 0x02, 0x0a, 0x0a, 0x4f, 0x70, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x14, - 0x0a, 0x10, 0x4f, 0x50, 0x45, 0x52, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, - 0x45, 0x54, 0x10, 0x00, 0x12, 0x18, 0x0a, 0x0d, 0x4f, 0x50, 0x45, 0x52, 0x53, 0x54, 0x41, 0x54, - 0x55, 0x53, 0x5f, 0x55, 0x50, 0x10, 0x02, 0x1a, 0x05, 0x82, 0x41, 0x02, 0x55, 0x50, 0x12, 0x1c, - 0x0a, 0x0f, 0x4f, 0x50, 0x45, 0x52, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x44, 0x4f, 0x57, - 0x4e, 0x10, 0x03, 0x1a, 0x07, 0x82, 0x41, 0x04, 0x44, 0x4f, 0x57, 0x4e, 0x12, 0x22, 0x0a, 0x12, - 0x4f, 0x50, 0x45, 0x52, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x54, 0x45, 0x53, 0x54, 0x49, - 0x4e, 0x47, 0x10, 0x04, 0x1a, 0x0a, 0x82, 0x41, 0x07, 0x54, 0x45, 0x53, 0x54, 0x49, 0x4e, 0x47, - 0x12, 0x22, 0x0a, 0x12, 0x4f, 0x50, 0x45, 0x52, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, - 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x05, 0x1a, 0x0a, 0x82, 0x41, 0x07, 0x55, 0x4e, 0x4b, - 0x4e, 0x4f, 0x57, 0x4e, 0x12, 0x22, 0x0a, 0x12, 0x4f, 0x50, 0x45, 0x52, 0x53, 0x54, 0x41, 0x54, - 0x55, 0x53, 0x5f, 0x44, 0x4f, 0x52, 0x4d, 0x41, 0x4e, 0x54, 0x10, 0x06, 0x1a, 0x0a, 0x82, 0x41, - 0x07, 0x44, 0x4f, 0x52, 0x4d, 0x41, 0x4e, 0x54, 0x12, 0x2a, 0x0a, 0x16, 0x4f, 0x50, 0x45, 0x52, - 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x50, 0x52, 0x45, 0x53, 0x45, - 0x4e, 0x54, 0x10, 0x07, 0x1a, 0x0e, 0x82, 0x41, 0x0b, 0x4e, 0x4f, 0x54, 0x5f, 0x50, 0x52, 0x45, - 0x53, 0x45, 0x4e, 0x54, 0x12, 0x34, 0x0a, 0x1b, 0x4f, 0x50, 0x45, 0x52, 0x53, 0x54, 0x41, 0x54, - 0x55, 0x53, 0x5f, 0x4c, 0x4f, 0x57, 0x45, 0x52, 0x5f, 0x4c, 0x41, 0x59, 0x45, 0x52, 0x5f, 0x44, - 0x4f, 0x57, 0x4e, 0x10, 0x08, 0x1a, 0x13, 0x82, 0x41, 0x10, 0x4c, 0x4f, 0x57, 0x45, 0x52, 0x5f, - 0x4c, 0x41, 0x59, 0x45, 0x52, 0x5f, 0x44, 0x4f, 0x57, 0x4e, 0x1a, 0xd9, 0x01, 0x0a, 0x0f, 0x53, - 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x4f, - 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x42, 0x39, 0x82, - 0x41, 0x36, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, - 0x75, 0x0a, 0x0c, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x51, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, - 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2e, 0x53, 0x75, - 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x53, 0x75, 0x62, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x52, 0x0c, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x1a, 0x97, 0x01, 0x0a, 0x0c, 0x49, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x31, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x1d, 0x82, 0x41, 0x1a, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x66, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2f, - 0x6e, 0x61, 0x6d, 0x65, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x54, 0x0a, 0x09, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x36, 0x2e, - 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, - 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x52, 0x09, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescOnce sync.Once - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescData = file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDesc -) - -func file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescGZIP() []byte { - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescOnce.Do(func() { - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescData = protoimpl.X.CompressGZIP(file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescData) - }) - return file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDescData -} - -var file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_enumTypes = make([]protoimpl.EnumInfo, 4) -var file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes = make([]protoimpl.MessageInfo, 15) -var file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_goTypes = []interface{}{ - (Interfaces_Interface_State_AdminStatus)(0), // 0: openconfig.openconfig_interfaces.Interfaces.Interface.State.AdminStatus - (Interfaces_Interface_State_OperStatus)(0), // 1: openconfig.openconfig_interfaces.Interfaces.Interface.State.OperStatus - (Interfaces_Interface_Subinterfaces_Subinterface_State_AdminStatus)(0), // 2: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.AdminStatus - (Interfaces_Interface_Subinterfaces_Subinterface_State_OperStatus)(0), // 3: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.OperStatus - (*Interfaces)(nil), // 4: openconfig.openconfig_interfaces.Interfaces - (*Interfaces_Interface)(nil), // 5: openconfig.openconfig_interfaces.Interfaces.Interface - (*Interfaces_InterfaceKey)(nil), // 6: openconfig.openconfig_interfaces.Interfaces.InterfaceKey - (*Interfaces_Interface_Config)(nil), // 7: openconfig.openconfig_interfaces.Interfaces.Interface.Config - (*Interfaces_Interface_HoldTime)(nil), // 8: openconfig.openconfig_interfaces.Interfaces.Interface.HoldTime - (*Interfaces_Interface_State)(nil), // 9: openconfig.openconfig_interfaces.Interfaces.Interface.State - (*Interfaces_Interface_Subinterfaces)(nil), // 10: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces - (*Interfaces_Interface_HoldTime_Config)(nil), // 11: openconfig.openconfig_interfaces.Interfaces.Interface.HoldTime.Config - (*Interfaces_Interface_HoldTime_State)(nil), // 12: openconfig.openconfig_interfaces.Interfaces.Interface.HoldTime.State - (*Interfaces_Interface_State_Counters)(nil), // 13: openconfig.openconfig_interfaces.Interfaces.Interface.State.Counters - (*Interfaces_Interface_Subinterfaces_Subinterface)(nil), // 14: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface - (*Interfaces_Interface_Subinterfaces_SubinterfaceKey)(nil), // 15: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.SubinterfaceKey - (*Interfaces_Interface_Subinterfaces_Subinterface_Config)(nil), // 16: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.Config - (*Interfaces_Interface_Subinterfaces_Subinterface_State)(nil), // 17: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State - (*Interfaces_Interface_Subinterfaces_Subinterface_State_Counters)(nil), // 18: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.Counters - (*ywrapper.StringValue)(nil), // 19: ywrapper.StringValue - (*ywrapper.BoolValue)(nil), // 20: ywrapper.BoolValue - (*ywrapper.UintValue)(nil), // 21: ywrapper.UintValue - (enums.IETFInterfacesInterfaceType)(0), // 22: openconfig.enums.IETFInterfacesInterfaceType -} -var file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_depIdxs = []int32{ - 6, // 0: openconfig.openconfig_interfaces.Interfaces.interface:type_name -> openconfig.openconfig_interfaces.Interfaces.InterfaceKey - 7, // 1: openconfig.openconfig_interfaces.Interfaces.Interface.config:type_name -> openconfig.openconfig_interfaces.Interfaces.Interface.Config - 8, // 2: openconfig.openconfig_interfaces.Interfaces.Interface.hold_time:type_name -> openconfig.openconfig_interfaces.Interfaces.Interface.HoldTime - 9, // 3: openconfig.openconfig_interfaces.Interfaces.Interface.state:type_name -> openconfig.openconfig_interfaces.Interfaces.Interface.State - 10, // 4: openconfig.openconfig_interfaces.Interfaces.Interface.subinterfaces:type_name -> openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces - 5, // 5: openconfig.openconfig_interfaces.Interfaces.InterfaceKey.interface:type_name -> openconfig.openconfig_interfaces.Interfaces.Interface - 19, // 6: openconfig.openconfig_interfaces.Interfaces.Interface.Config.description:type_name -> ywrapper.StringValue - 20, // 7: openconfig.openconfig_interfaces.Interfaces.Interface.Config.enabled:type_name -> ywrapper.BoolValue - 20, // 8: openconfig.openconfig_interfaces.Interfaces.Interface.Config.loopback_mode:type_name -> ywrapper.BoolValue - 21, // 9: openconfig.openconfig_interfaces.Interfaces.Interface.Config.mtu:type_name -> ywrapper.UintValue - 19, // 10: openconfig.openconfig_interfaces.Interfaces.Interface.Config.name:type_name -> ywrapper.StringValue - 22, // 11: openconfig.openconfig_interfaces.Interfaces.Interface.Config.type:type_name -> openconfig.enums.IETFInterfacesInterfaceType - 11, // 12: openconfig.openconfig_interfaces.Interfaces.Interface.HoldTime.config:type_name -> openconfig.openconfig_interfaces.Interfaces.Interface.HoldTime.Config - 12, // 13: openconfig.openconfig_interfaces.Interfaces.Interface.HoldTime.state:type_name -> openconfig.openconfig_interfaces.Interfaces.Interface.HoldTime.State - 0, // 14: openconfig.openconfig_interfaces.Interfaces.Interface.State.admin_status:type_name -> openconfig.openconfig_interfaces.Interfaces.Interface.State.AdminStatus - 13, // 15: openconfig.openconfig_interfaces.Interfaces.Interface.State.counters:type_name -> openconfig.openconfig_interfaces.Interfaces.Interface.State.Counters - 19, // 16: openconfig.openconfig_interfaces.Interfaces.Interface.State.description:type_name -> ywrapper.StringValue - 20, // 17: openconfig.openconfig_interfaces.Interfaces.Interface.State.enabled:type_name -> ywrapper.BoolValue - 21, // 18: openconfig.openconfig_interfaces.Interfaces.Interface.State.ifindex:type_name -> ywrapper.UintValue - 21, // 19: openconfig.openconfig_interfaces.Interfaces.Interface.State.last_change:type_name -> ywrapper.UintValue - 20, // 20: openconfig.openconfig_interfaces.Interfaces.Interface.State.logical:type_name -> ywrapper.BoolValue - 20, // 21: openconfig.openconfig_interfaces.Interfaces.Interface.State.loopback_mode:type_name -> ywrapper.BoolValue - 21, // 22: openconfig.openconfig_interfaces.Interfaces.Interface.State.mtu:type_name -> ywrapper.UintValue - 19, // 23: openconfig.openconfig_interfaces.Interfaces.Interface.State.name:type_name -> ywrapper.StringValue - 1, // 24: openconfig.openconfig_interfaces.Interfaces.Interface.State.oper_status:type_name -> openconfig.openconfig_interfaces.Interfaces.Interface.State.OperStatus - 22, // 25: openconfig.openconfig_interfaces.Interfaces.Interface.State.type:type_name -> openconfig.enums.IETFInterfacesInterfaceType - 15, // 26: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.subinterface:type_name -> openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.SubinterfaceKey - 21, // 27: openconfig.openconfig_interfaces.Interfaces.Interface.HoldTime.Config.down:type_name -> ywrapper.UintValue - 21, // 28: openconfig.openconfig_interfaces.Interfaces.Interface.HoldTime.Config.up:type_name -> ywrapper.UintValue - 21, // 29: openconfig.openconfig_interfaces.Interfaces.Interface.HoldTime.State.down:type_name -> ywrapper.UintValue - 21, // 30: openconfig.openconfig_interfaces.Interfaces.Interface.HoldTime.State.up:type_name -> ywrapper.UintValue - 21, // 31: openconfig.openconfig_interfaces.Interfaces.Interface.State.Counters.carrier_transitions:type_name -> ywrapper.UintValue - 21, // 32: openconfig.openconfig_interfaces.Interfaces.Interface.State.Counters.in_broadcast_pkts:type_name -> ywrapper.UintValue - 21, // 33: openconfig.openconfig_interfaces.Interfaces.Interface.State.Counters.in_discards:type_name -> ywrapper.UintValue - 21, // 34: openconfig.openconfig_interfaces.Interfaces.Interface.State.Counters.in_errors:type_name -> ywrapper.UintValue - 21, // 35: openconfig.openconfig_interfaces.Interfaces.Interface.State.Counters.in_fcs_errors:type_name -> ywrapper.UintValue - 21, // 36: openconfig.openconfig_interfaces.Interfaces.Interface.State.Counters.in_multicast_pkts:type_name -> ywrapper.UintValue - 21, // 37: openconfig.openconfig_interfaces.Interfaces.Interface.State.Counters.in_octets:type_name -> ywrapper.UintValue - 21, // 38: openconfig.openconfig_interfaces.Interfaces.Interface.State.Counters.in_pkts:type_name -> ywrapper.UintValue - 21, // 39: openconfig.openconfig_interfaces.Interfaces.Interface.State.Counters.in_unicast_pkts:type_name -> ywrapper.UintValue - 21, // 40: openconfig.openconfig_interfaces.Interfaces.Interface.State.Counters.in_unknown_protos:type_name -> ywrapper.UintValue - 21, // 41: openconfig.openconfig_interfaces.Interfaces.Interface.State.Counters.last_clear:type_name -> ywrapper.UintValue - 21, // 42: openconfig.openconfig_interfaces.Interfaces.Interface.State.Counters.out_broadcast_pkts:type_name -> ywrapper.UintValue - 21, // 43: openconfig.openconfig_interfaces.Interfaces.Interface.State.Counters.out_discards:type_name -> ywrapper.UintValue - 21, // 44: openconfig.openconfig_interfaces.Interfaces.Interface.State.Counters.out_errors:type_name -> ywrapper.UintValue - 21, // 45: openconfig.openconfig_interfaces.Interfaces.Interface.State.Counters.out_multicast_pkts:type_name -> ywrapper.UintValue - 21, // 46: openconfig.openconfig_interfaces.Interfaces.Interface.State.Counters.out_octets:type_name -> ywrapper.UintValue - 21, // 47: openconfig.openconfig_interfaces.Interfaces.Interface.State.Counters.out_pkts:type_name -> ywrapper.UintValue - 21, // 48: openconfig.openconfig_interfaces.Interfaces.Interface.State.Counters.out_unicast_pkts:type_name -> ywrapper.UintValue - 16, // 49: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.config:type_name -> openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.Config - 17, // 50: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.state:type_name -> openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State - 14, // 51: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.SubinterfaceKey.subinterface:type_name -> openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface - 19, // 52: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.Config.description:type_name -> ywrapper.StringValue - 20, // 53: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.Config.enabled:type_name -> ywrapper.BoolValue - 21, // 54: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.Config.index:type_name -> ywrapper.UintValue - 2, // 55: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.admin_status:type_name -> openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.AdminStatus - 18, // 56: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.counters:type_name -> openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.Counters - 19, // 57: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.description:type_name -> ywrapper.StringValue - 20, // 58: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.enabled:type_name -> ywrapper.BoolValue - 21, // 59: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.ifindex:type_name -> ywrapper.UintValue - 21, // 60: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.index:type_name -> ywrapper.UintValue - 21, // 61: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.last_change:type_name -> ywrapper.UintValue - 20, // 62: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.logical:type_name -> ywrapper.BoolValue - 19, // 63: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.name:type_name -> ywrapper.StringValue - 3, // 64: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.oper_status:type_name -> openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.OperStatus - 21, // 65: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.Counters.carrier_transitions:type_name -> ywrapper.UintValue - 21, // 66: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.Counters.in_broadcast_pkts:type_name -> ywrapper.UintValue - 21, // 67: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.Counters.in_discards:type_name -> ywrapper.UintValue - 21, // 68: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.Counters.in_errors:type_name -> ywrapper.UintValue - 21, // 69: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.Counters.in_fcs_errors:type_name -> ywrapper.UintValue - 21, // 70: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.Counters.in_multicast_pkts:type_name -> ywrapper.UintValue - 21, // 71: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.Counters.in_octets:type_name -> ywrapper.UintValue - 21, // 72: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.Counters.in_pkts:type_name -> ywrapper.UintValue - 21, // 73: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.Counters.in_unicast_pkts:type_name -> ywrapper.UintValue - 21, // 74: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.Counters.in_unknown_protos:type_name -> ywrapper.UintValue - 21, // 75: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.Counters.last_clear:type_name -> ywrapper.UintValue - 21, // 76: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.Counters.out_broadcast_pkts:type_name -> ywrapper.UintValue - 21, // 77: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.Counters.out_discards:type_name -> ywrapper.UintValue - 21, // 78: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.Counters.out_errors:type_name -> ywrapper.UintValue - 21, // 79: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.Counters.out_multicast_pkts:type_name -> ywrapper.UintValue - 21, // 80: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.Counters.out_octets:type_name -> ywrapper.UintValue - 21, // 81: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.Counters.out_pkts:type_name -> ywrapper.UintValue - 21, // 82: openconfig.openconfig_interfaces.Interfaces.Interface.Subinterfaces.Subinterface.State.Counters.out_unicast_pkts:type_name -> ywrapper.UintValue - 83, // [83:83] is the sub-list for method output_type - 83, // [83:83] is the sub-list for method input_type - 83, // [83:83] is the sub-list for extension type_name - 83, // [83:83] is the sub-list for extension extendee - 0, // [0:83] is the sub-list for field type_name -} - -func init() { file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_init() } -func file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_init() { - if File_openconfig_openconfig_interfaces_openconfig_interfaces_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Interfaces); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Interfaces_Interface); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Interfaces_InterfaceKey); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Interfaces_Interface_Config); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Interfaces_Interface_HoldTime); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Interfaces_Interface_State); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Interfaces_Interface_Subinterfaces); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Interfaces_Interface_HoldTime_Config); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Interfaces_Interface_HoldTime_State); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Interfaces_Interface_State_Counters); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Interfaces_Interface_Subinterfaces_Subinterface); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Interfaces_Interface_Subinterfaces_SubinterfaceKey); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Interfaces_Interface_Subinterfaces_Subinterface_Config); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Interfaces_Interface_Subinterfaces_Subinterface_State); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Interfaces_Interface_Subinterfaces_Subinterface_State_Counters); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDesc, - NumEnums: 4, - NumMessages: 15, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_goTypes, - DependencyIndexes: file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_depIdxs, - EnumInfos: file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_enumTypes, - MessageInfos: file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_msgTypes, - }.Build() - File_openconfig_openconfig_interfaces_openconfig_interfaces_proto = out.File - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_rawDesc = nil - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_goTypes = nil - file_openconfig_openconfig_interfaces_openconfig_interfaces_proto_depIdxs = nil -} diff --git a/api/proto/openconfig/openconfig_interfaces/openconfig_interfaces.proto b/api/proto/openconfig/openconfig_interfaces/openconfig_interfaces.proto deleted file mode 100644 index 82e99cf6a44d260a1b0b115802b4f55a214c9561..0000000000000000000000000000000000000000 --- a/api/proto/openconfig/openconfig_interfaces/openconfig_interfaces.proto +++ /dev/null @@ -1,163 +0,0 @@ -// openconfig.openconfig_interfaces is generated by proto_generator as a protobuf -// representation of a YANG schema. -// -// Input schema modules: -// - ../yang-models/models/openconfig/release/models/interfaces/openconfig-interfaces.yang -// Include paths: -// - ../yang-models/models/... -syntax = "proto3"; - -package openconfig.openconfig_interfaces; -option go_package = "code.fbi.h-da.de/cocsn/gosdn"; - -import "github.com/openconfig/ygot/proto/ywrapper/ywrapper.proto"; -import "github.com/openconfig/ygot/proto/yext/yext.proto"; -import "openconfig/enums/enums.proto"; - -message Interfaces { - message Interface { - message Config { - ywrapper.StringValue description = 418535860 [(yext.schemapath) = "/interfaces/interface/config/description"]; - ywrapper.BoolValue enabled = 37224301 [(yext.schemapath) = "/interfaces/interface/config/enabled"]; - ywrapper.BoolValue loopback_mode = 253516347 [(yext.schemapath) = "/interfaces/interface/config/loopback-mode"]; - ywrapper.UintValue mtu = 376210342 [(yext.schemapath) = "/interfaces/interface/config/mtu"]; - ywrapper.StringValue name = 51804187 [(yext.schemapath) = "/interfaces/interface/config/name"]; - openconfig.enums.IETFInterfacesInterfaceType type = 144596894 [(yext.schemapath) = "/interfaces/interface/config/type"]; - } - message HoldTime { - message Config { - ywrapper.UintValue down = 171181656 [(yext.schemapath) = "/interfaces/interface/hold-time/config/down"]; - ywrapper.UintValue up = 62026235 [(yext.schemapath) = "/interfaces/interface/hold-time/config/up"]; - } - message State { - ywrapper.UintValue down = 167887721 [(yext.schemapath) = "/interfaces/interface/hold-time/state/down"]; - ywrapper.UintValue up = 223847598 [(yext.schemapath) = "/interfaces/interface/hold-time/state/up"]; - } - Config config = 316512729 [(yext.schemapath) = "/interfaces/interface/hold-time/config"]; - State state = 483010990 [(yext.schemapath) = "/interfaces/interface/hold-time/state"]; - } - message State { - message Counters { - ywrapper.UintValue carrier_transitions = 270803130 [(yext.schemapath) = "/interfaces/interface/state/counters/carrier-transitions"]; - ywrapper.UintValue in_broadcast_pkts = 280201989 [(yext.schemapath) = "/interfaces/interface/state/counters/in-broadcast-pkts"]; - ywrapper.UintValue in_discards = 11979514 [(yext.schemapath) = "/interfaces/interface/state/counters/in-discards"]; - ywrapper.UintValue in_errors = 456697578 [(yext.schemapath) = "/interfaces/interface/state/counters/in-errors"]; - ywrapper.UintValue in_fcs_errors = 501559027 [(yext.schemapath) = "/interfaces/interface/state/counters/in-fcs-errors"]; - ywrapper.UintValue in_multicast_pkts = 113269128 [(yext.schemapath) = "/interfaces/interface/state/counters/in-multicast-pkts"]; - ywrapper.UintValue in_octets = 333138891 [(yext.schemapath) = "/interfaces/interface/state/counters/in-octets"]; - ywrapper.UintValue in_pkts = 412843491 [(yext.schemapath) = "/interfaces/interface/state/counters/in-pkts"]; - ywrapper.UintValue in_unicast_pkts = 272792307 [(yext.schemapath) = "/interfaces/interface/state/counters/in-unicast-pkts"]; - ywrapper.UintValue in_unknown_protos = 241475497 [(yext.schemapath) = "/interfaces/interface/state/counters/in-unknown-protos"]; - ywrapper.UintValue last_clear = 186014919 [(yext.schemapath) = "/interfaces/interface/state/counters/last-clear"]; - ywrapper.UintValue out_broadcast_pkts = 338589668 [(yext.schemapath) = "/interfaces/interface/state/counters/out-broadcast-pkts"]; - ywrapper.UintValue out_discards = 254055111 [(yext.schemapath) = "/interfaces/interface/state/counters/out-discards"]; - ywrapper.UintValue out_errors = 471103047 [(yext.schemapath) = "/interfaces/interface/state/counters/out-errors"]; - ywrapper.UintValue out_multicast_pkts = 457840757 [(yext.schemapath) = "/interfaces/interface/state/counters/out-multicast-pkts"]; - ywrapper.UintValue out_octets = 201005514 [(yext.schemapath) = "/interfaces/interface/state/counters/out-octets"]; - ywrapper.UintValue out_pkts = 437582090 [(yext.schemapath) = "/interfaces/interface/state/counters/out-pkts"]; - ywrapper.UintValue out_unicast_pkts = 36542246 [(yext.schemapath) = "/interfaces/interface/state/counters/out-unicast-pkts"]; - } - enum AdminStatus { - ADMINSTATUS_UNSET = 0; - ADMINSTATUS_UP = 1 [(yext.yang_name) = "UP"]; - ADMINSTATUS_DOWN = 2 [(yext.yang_name) = "DOWN"]; - ADMINSTATUS_TESTING = 3 [(yext.yang_name) = "TESTING"]; - } - enum OperStatus { - OPERSTATUS_UNSET = 0; - OPERSTATUS_UP = 2 [(yext.yang_name) = "UP"]; - OPERSTATUS_DOWN = 3 [(yext.yang_name) = "DOWN"]; - OPERSTATUS_TESTING = 4 [(yext.yang_name) = "TESTING"]; - OPERSTATUS_UNKNOWN = 5 [(yext.yang_name) = "UNKNOWN"]; - OPERSTATUS_DORMANT = 6 [(yext.yang_name) = "DORMANT"]; - OPERSTATUS_NOT_PRESENT = 7 [(yext.yang_name) = "NOT_PRESENT"]; - OPERSTATUS_LOWER_LAYER_DOWN = 8 [(yext.yang_name) = "LOWER_LAYER_DOWN"]; - } - AdminStatus admin_status = 474494763 [(yext.schemapath) = "/interfaces/interface/state/admin-status"]; - Counters counters = 83645964 [(yext.schemapath) = "/interfaces/interface/state/counters"]; - ywrapper.StringValue description = 389435287 [(yext.schemapath) = "/interfaces/interface/state/description"]; - ywrapper.BoolValue enabled = 330927518 [(yext.schemapath) = "/interfaces/interface/state/enabled"]; - ywrapper.UintValue ifindex = 116108202 [(yext.schemapath) = "/interfaces/interface/state/ifindex"]; - ywrapper.UintValue last_change = 127348880 [(yext.schemapath) = "/interfaces/interface/state/last-change"]; - ywrapper.BoolValue logical = 440460216 [(yext.schemapath) = "/interfaces/interface/state/logical"]; - ywrapper.BoolValue loopback_mode = 372935512 [(yext.schemapath) = "/interfaces/interface/state/loopback-mode"]; - ywrapper.UintValue mtu = 96390485 [(yext.schemapath) = "/interfaces/interface/state/mtu"]; - ywrapper.StringValue name = 503495278 [(yext.schemapath) = "/interfaces/interface/state/name"]; - OperStatus oper_status = 470394226 [(yext.schemapath) = "/interfaces/interface/state/oper-status"]; - openconfig.enums.IETFInterfacesInterfaceType type = 358148579 [(yext.schemapath) = "/interfaces/interface/state/type"]; - } - message Subinterfaces { - message Subinterface { - message Config { - ywrapper.StringValue description = 280671199 [(yext.schemapath) = "/interfaces/interface/subinterfaces/subinterface/config/description"]; - ywrapper.BoolValue enabled = 297236390 [(yext.schemapath) = "/interfaces/interface/subinterfaces/subinterface/config/enabled"]; - ywrapper.UintValue index = 279269781 [(yext.schemapath) = "/interfaces/interface/subinterfaces/subinterface/config/index"]; - } - message State { - message Counters { - ywrapper.UintValue carrier_transitions = 141120277 [(yext.schemapath) = "/interfaces/interface/subinterfaces/subinterface/state/counters/carrier-transitions"]; - ywrapper.UintValue in_broadcast_pkts = 120244022 [(yext.schemapath) = "/interfaces/interface/subinterfaces/subinterface/state/counters/in-broadcast-pkts"]; - ywrapper.UintValue in_discards = 307490461 [(yext.schemapath) = "/interfaces/interface/subinterfaces/subinterface/state/counters/in-discards"]; - ywrapper.UintValue in_errors = 319720873 [(yext.schemapath) = "/interfaces/interface/subinterfaces/subinterface/state/counters/in-errors"]; - ywrapper.UintValue in_fcs_errors = 169858424 [(yext.schemapath) = "/interfaces/interface/subinterfaces/subinterface/state/counters/in-fcs-errors"]; - ywrapper.UintValue in_multicast_pkts = 320618859 [(yext.schemapath) = "/interfaces/interface/subinterfaces/subinterface/state/counters/in-multicast-pkts"]; - ywrapper.UintValue in_octets = 530205868 [(yext.schemapath) = "/interfaces/interface/subinterfaces/subinterface/state/counters/in-octets"]; - ywrapper.UintValue in_pkts = 441153352 [(yext.schemapath) = "/interfaces/interface/subinterfaces/subinterface/state/counters/in-pkts"]; - ywrapper.UintValue in_unicast_pkts = 177838880 [(yext.schemapath) = "/interfaces/interface/subinterfaces/subinterface/state/counters/in-unicast-pkts"]; - ywrapper.UintValue in_unknown_protos = 146059814 [(yext.schemapath) = "/interfaces/interface/subinterfaces/subinterface/state/counters/in-unknown-protos"]; - ywrapper.UintValue last_clear = 518046966 [(yext.schemapath) = "/interfaces/interface/subinterfaces/subinterface/state/counters/last-clear"]; - ywrapper.UintValue out_broadcast_pkts = 501221245 [(yext.schemapath) = "/interfaces/interface/subinterfaces/subinterface/state/counters/out-broadcast-pkts"]; - ywrapper.UintValue out_discards = 159539762 [(yext.schemapath) = "/interfaces/interface/subinterfaces/subinterface/state/counters/out-discards"]; - ywrapper.UintValue out_errors = 466636898 [(yext.schemapath) = "/interfaces/interface/subinterfaces/subinterface/state/counters/out-errors"]; - ywrapper.UintValue out_multicast_pkts = 326155776 [(yext.schemapath) = "/interfaces/interface/subinterfaces/subinterface/state/counters/out-multicast-pkts"]; - ywrapper.UintValue out_octets = 50579235 [(yext.schemapath) = "/interfaces/interface/subinterfaces/subinterface/state/counters/out-octets"]; - ywrapper.UintValue out_pkts = 29497115 [(yext.schemapath) = "/interfaces/interface/subinterfaces/subinterface/state/counters/out-pkts"]; - ywrapper.UintValue out_unicast_pkts = 297910971 [(yext.schemapath) = "/interfaces/interface/subinterfaces/subinterface/state/counters/out-unicast-pkts"]; - } - enum AdminStatus { - ADMINSTATUS_UNSET = 0; - ADMINSTATUS_UP = 1 [(yext.yang_name) = "UP"]; - ADMINSTATUS_DOWN = 2 [(yext.yang_name) = "DOWN"]; - ADMINSTATUS_TESTING = 3 [(yext.yang_name) = "TESTING"]; - } - enum OperStatus { - OPERSTATUS_UNSET = 0; - OPERSTATUS_UP = 2 [(yext.yang_name) = "UP"]; - OPERSTATUS_DOWN = 3 [(yext.yang_name) = "DOWN"]; - OPERSTATUS_TESTING = 4 [(yext.yang_name) = "TESTING"]; - OPERSTATUS_UNKNOWN = 5 [(yext.yang_name) = "UNKNOWN"]; - OPERSTATUS_DORMANT = 6 [(yext.yang_name) = "DORMANT"]; - OPERSTATUS_NOT_PRESENT = 7 [(yext.yang_name) = "NOT_PRESENT"]; - OPERSTATUS_LOWER_LAYER_DOWN = 8 [(yext.yang_name) = "LOWER_LAYER_DOWN"]; - } - AdminStatus admin_status = 250658952 [(yext.schemapath) = "/interfaces/interface/subinterfaces/subinterface/state/admin-status"]; - Counters counters = 483442783 [(yext.schemapath) = "/interfaces/interface/subinterfaces/subinterface/state/counters"]; - ywrapper.StringValue description = 49943526 [(yext.schemapath) = "/interfaces/interface/subinterfaces/subinterface/state/description"]; - ywrapper.BoolValue enabled = 468513843 [(yext.schemapath) = "/interfaces/interface/subinterfaces/subinterface/state/enabled"]; - ywrapper.UintValue ifindex = 511987815 [(yext.schemapath) = "/interfaces/interface/subinterfaces/subinterface/state/ifindex"]; - ywrapper.UintValue index = 80745756 [(yext.schemapath) = "/interfaces/interface/subinterfaces/subinterface/state/index"]; - ywrapper.UintValue last_change = 29904521 [(yext.schemapath) = "/interfaces/interface/subinterfaces/subinterface/state/last-change"]; - ywrapper.BoolValue logical = 294124401 [(yext.schemapath) = "/interfaces/interface/subinterfaces/subinterface/state/logical"]; - ywrapper.StringValue name = 279346681 [(yext.schemapath) = "/interfaces/interface/subinterfaces/subinterface/state/name"]; - OperStatus oper_status = 401969247 [(yext.schemapath) = "/interfaces/interface/subinterfaces/subinterface/state/oper-status"]; - } - Config config = 175001476 [(yext.schemapath) = "/interfaces/interface/subinterfaces/subinterface/config"]; - State state = 501974173 [(yext.schemapath) = "/interfaces/interface/subinterfaces/subinterface/state"]; - } - message SubinterfaceKey { - uint64 index = 1 [(yext.schemapath) = "/interfaces/interface/subinterfaces/subinterface/index"]; - Subinterface subinterface = 2; - } - repeated SubinterfaceKey subinterface = 464802819 [(yext.schemapath) = "/interfaces/interface/subinterfaces/subinterface"]; - } - Config config = 334174827 [(yext.schemapath) = "/interfaces/interface/config"]; - HoldTime hold_time = 175931092 [(yext.schemapath) = "/interfaces/interface/hold-time"]; - State state = 387556140 [(yext.schemapath) = "/interfaces/interface/state"]; - Subinterfaces subinterfaces = 327798165 [(yext.schemapath) = "/interfaces/interface/subinterfaces"]; - } - message InterfaceKey { - string name = 1 [(yext.schemapath) = "/interfaces/interface/name"]; - Interface interface = 2; - } - repeated InterfaceKey interface = 422482938 [(yext.schemapath) = "/interfaces/interface"]; -} diff --git a/build/cd/deploy.go b/build/cd/deploy.go deleted file mode 100644 index 7f61e2db03aa957787167eb5112399771b6b33d9..0000000000000000000000000000000000000000 --- a/build/cd/deploy.go +++ /dev/null @@ -1,398 +0,0 @@ -package main - -import ( - "context" - "os" - - "code.fbi.h-da.de/cocsn/gosdn/nucleus" - log "github.com/sirupsen/logrus" - appv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - netv1 "k8s.io/api/networking/v1beta1" - "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/intstr" - "k8s.io/client-go/kubernetes" - "k8s.io/client-go/tools/clientcmd" -) - -func main() { - log.SetFormatter(&log.JSONFormatter{}) - kubeconfig, err := clientcmd.BuildConfigFromFlags("https://api.ocp.fbi.h-da.de:6443", "") - if err != nil { - log.Fatal(err) - } - kubeconfig.BearerToken = os.Getenv("K8S_DEPLOY_TOKEN") - clientset, err := kubernetes.NewForConfig(kubeconfig) - if err != nil { - log.Fatal(err) - } - var tag string - switch os.Getenv("CI_COMMIT_BRANCH") { - case os.Getenv("CI_DEFAULT_BRANCH"): - tag = "latest" - case "develop": - tag = "develop" - default: - tag = os.Getenv("CI_COMMIT_SHA") - } - - switch os.Getenv("CI_NIGHTLY") { - case "mainline": - tag = "nightly" - case "develop": - tag = "nightly-develop" - default: - tag = os.Getenv("CI_COMMIT_SHA") - } - - switch os.Getenv("K8S_OP") { - case "create": - if err := create(clientset, tag); err != nil { - log.Fatal(err) - } - case "delete": - if err := remove(clientset, tag); err != nil { - log.Fatal(err) - } - default: - log.Fatal("invalid option") - } -} - -// nolint -func create(clientset *kubernetes.Clientset, tag string) error { - env := "gosdn-" + tag - service := createService(env) - ingress := createIngress(env) - config := createConfigMap(env) - deployment := createDeployment(env, tag) - opts := metav1.CreateOptions{} - ctx := context.Background() - _, err := clientset.CoreV1().Services("cocsn").Create(ctx, service, opts) - if err != nil { - switch err.(type) { - case *errors.StatusError: - if err.(*errors.StatusError).ErrStatus.Code == 409 { - if err := update(clientset, service, env); err != nil { - return err - } - } else { - log.Error(err) - } - default: - log.Error(err) - } - } else { - log.Printf("service %v created", service.Name) - } - _, err = clientset.NetworkingV1beta1().Ingresses("cocsn").Create(ctx, ingress, opts) - if err != nil { - switch err.(type) { - case *errors.StatusError: - if err.(*errors.StatusError).ErrStatus.Code == 409 { - if err := update(clientset, ingress, env); err != nil { - log.Error(err) - } - } else { - log.Error(err) - } - default: - log.Error(err) - } - } else { - log.Printf("ingress %v created", ingress.Name) - } - _, err = clientset.CoreV1().ConfigMaps("cocsn").Create(ctx, config, opts) - if err != nil { - switch err.(type) { - case *errors.StatusError: - if err.(*errors.StatusError).ErrStatus.Code == 409 { - if err := update(clientset, config, env); err != nil { - log.Error(err) - } - } else { - log.Error(err) - } - default: - log.Error(err) - } - } else { - log.Printf("configMap %v created", config.Name) - } - _, err = clientset.AppsV1().Deployments("cocsn").Create(ctx, deployment, opts) - if err != nil { - switch err.(type) { - case *errors.StatusError: - if err.(*errors.StatusError).ErrStatus.Code == 409 { - if err := update(clientset, deployment, env); err != nil { - log.Error(err) - } - } else { - log.Error(err) - } - default: - log.Error(err) - } - } else { - log.Printf("deployment %v created", deployment.Name) - } - return nil -} - -func update(clientset *kubernetes.Clientset, resource metav1.Common, env string) error { - opts := metav1.UpdateOptions{} - getOpts := metav1.GetOptions{} - ctx := context.Background() - switch resource.(type) { - case *corev1.Service: - service := resource.(*corev1.Service) - s, err := clientset.CoreV1().Services("cocsn").Get(ctx, env, getOpts) - if err != nil { - return err - } - s.DeepCopyInto(service) - _, err = clientset.CoreV1().Services("cocsn").Update(ctx, service, opts) - if err != nil { - return err - } - log.Printf("service %v updated", service.Name) - case *netv1.Ingress: - ingress := resource.(*netv1.Ingress) - i, err := clientset.NetworkingV1beta1().Ingresses("cocsn").Get(ctx, env, getOpts) - if err != nil { - return err - } - i.DeepCopyInto(ingress) - _, err = clientset.NetworkingV1beta1().Ingresses("cocsn").Update(ctx, ingress, opts) - if err != nil { - return err - } - log.Printf("ingress %v updated", ingress.Name) - case *corev1.ConfigMap: - config := resource.(*corev1.ConfigMap) - c, err := clientset.CoreV1().ConfigMaps("cocsn").Get(ctx, env+"-config", getOpts) - if err != nil { - return err - } - c.DeepCopyInto(config) - _, err = clientset.CoreV1().ConfigMaps("cocsn").Update(ctx, config, opts) - if err != nil { - return err - } - log.Printf("configMap %v updated", config.Name) - case *appv1.Deployment: - deployment := resource.(*appv1.Deployment) - d, err := clientset.AppsV1().Deployments("cocsn").Get(ctx, env, getOpts) - if err != nil { - return err - } - d.DeepCopyInto(deployment) - _, err = clientset.AppsV1().Deployments("cocsn").Update(ctx, deployment, opts) - if err != nil { - return err - } - log.Printf("deployment %v updated", deployment.Name) - default: - return &nucleus.ErrInvalidParameters{} - } - return nil -} - -func remove(clientset *kubernetes.Clientset, tag string) error { - env := "gosdn-" + tag - opts := metav1.DeleteOptions{} - ctx := context.Background() - err := clientset.CoreV1().Services("cocsn").Delete(ctx, env, opts) - if err != nil { - log.Error(err) - } else { - log.Printf("service %v deleted", env) - } - err = clientset.CoreV1().ConfigMaps("cocsn").Delete(ctx, env+"-config", opts) - if err != nil { - log.Error(err) - } else { - log.Printf("config %v deleted", env+"-config") - } - err = clientset.AppsV1().Deployments("cocsn").Delete(ctx, env, opts) - if err != nil { - log.Error(err) - } else { - log.Printf("deployment %v deleted", env) - } - err = clientset.NetworkingV1beta1().Ingresses("cocsn").Delete(ctx, env, opts) - if err != nil { - log.Error(err) - } else { - log.Printf("ingress %v deleted", env) - } - return err -} - -func createService(environment string) *corev1.Service { - return &corev1.Service{ - TypeMeta: metav1.TypeMeta{ - Kind: "Service", - APIVersion: "v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: environment, - Namespace: "cocsn", - Labels: map[string]string{"run": environment}, - }, - Spec: corev1.ServiceSpec{ - Ports: []corev1.ServicePort{ - { - Name: "http", - Port: 8080, - TargetPort: intstr.IntOrString{IntVal: 8080}, - }, - { - Name: "grpc", - Port: 55055, - TargetPort: intstr.IntOrString{IntVal: 55055}, - }, - }, - Selector: map[string]string{"run": environment}, - Type: "NodePort", - ExternalName: environment + ".apps.ocp.fbi.h-da.de", - }, - } -} - -func createDeployment(environment, hash string) *appv1.Deployment { - return &appv1.Deployment{ - TypeMeta: metav1.TypeMeta{ - Kind: "Deployment", - APIVersion: "apps/v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: environment, - }, - Spec: appv1.DeploymentSpec{ - Selector: &metav1.LabelSelector{ - MatchLabels: map[string]string{"run": environment}, - }, - Template: corev1.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Labels: map[string]string{"run": environment}, - }, - Spec: corev1.PodSpec{ - Volumes: []corev1.Volume{ - { - Name: "gosdn-config-volume", - VolumeSource: corev1.VolumeSource{ - ConfigMap: &corev1.ConfigMapVolumeSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: environment + "-config", - }, - }, - }, - }, - }, - Containers: []corev1.Container{ - { - Name: "gosdn", - Image: "registry.code.fbi.h-da.de/cocsn/gosdn:" + hash, - Command: nil, - Args: nil, - WorkingDir: "", - Ports: []corev1.ContainerPort{ - { - Name: "grpc", - ContainerPort: 55055, - }, - { - Name: "http", - ContainerPort: 8080, - }, - }, - VolumeMounts: []corev1.VolumeMount{ - { - Name: "gosdn-config-volume", - MountPath: "/usr/local/etc/gosdn/gosdn.toml", - }, - }, - LivenessProbe: &corev1.Probe{ - Handler: corev1.Handler{ - HTTPGet: &corev1.HTTPGetAction{ - Path: "/livez", - Port: intstr.IntOrString{IntVal: 8080}, - }, - }, - InitialDelaySeconds: 5, - PeriodSeconds: 2, - }, - ReadinessProbe: &corev1.Probe{ - Handler: corev1.Handler{ - HTTPGet: &corev1.HTTPGetAction{ - Path: "/readyz", - Port: intstr.IntOrString{IntVal: 8080}, - }, - }, - InitialDelaySeconds: 10, - PeriodSeconds: 2, - }, - ImagePullPolicy: "Always", - }, - }, - ImagePullSecrets: []corev1.LocalObjectReference{ - {Name: "k8s-gosdn-test"}, - }, - }, - }, - Strategy: appv1.DeploymentStrategy{ - Type: "RollingUpdate", - RollingUpdate: &appv1.RollingUpdateDeployment{}, - }, - }, - } -} - -func createConfigMap(env string) *corev1.ConfigMap { - return &corev1.ConfigMap{ - TypeMeta: metav1.TypeMeta{ - Kind: "ConfigMap", - APIVersion: "v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: env + "-config", - }, - Data: map[string]string{"gosdn.toml": "#empty"}, - } -} - -func createIngress(env string) *netv1.Ingress { - return &netv1.Ingress{ - TypeMeta: metav1.TypeMeta{ - Kind: "Ingress", - APIVersion: "v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: env, - Namespace: "cocsn", - }, - Spec: netv1.IngressSpec{ - Rules: []netv1.IngressRule{ - { - Host: env + ".apps.ocp.fbi.h-da.de", - IngressRuleValue: netv1.IngressRuleValue{ - HTTP: &netv1.HTTPIngressRuleValue{ - Paths: []netv1.HTTPIngressPath{ - { - Path: "/api", - Backend: netv1.IngressBackend{ - ServiceName: env, - ServicePort: intstr.IntOrString{IntVal: 8080}, - }, - }, - }, - }, - }, - }, - }, - }, - Status: netv1.IngressStatus{}, - } -} diff --git a/build/ci/.build-container.yml b/build/ci/.build-container.yml deleted file mode 100644 index 8a092f8a3f88e0b8147052d8032219379d68e294..0000000000000000000000000000000000000000 --- a/build/ci/.build-container.yml +++ /dev/null @@ -1,64 +0,0 @@ - -services: - - docker:19.03.12-dind - -variables: - DOCKER_TLS_CERTDIR: "/certs" - DOCKER_IMAGE_SHA: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA - -.build: &build - before_script: - - echo "override global before script" - image: docker:19.03.12 - stage: build - tags: - - dind - script: - - > - docker build \ - --build-arg GITLAB_USER=$GO_MODULES_USER \ - --build-arg GITLAB_TOKEN=$GO_MODULES_ACCESS_TOKEN \ - --build-arg BUILDARGS=$BUILDARGS \ - -t $DOCKER_IMAGE_SHA . - - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY - - docker push $DOCKER_IMAGE_SHA - - docker tag $DOCKER_IMAGE_SHA $TAG - - docker push $TAG - -build:develop: - variables: - TAG: $CI_REGISTRY_IMAGE:develop - BUILDARGS: -race - rules: - - if: $CI_COMMIT_BRANCH == "develop" && $CI_NIGHTLY == null - <<: *build - -build:nightly:develop: - variables: - TAG: $CI_REGISTRY_IMAGE:nightly-develop - BUILDARGS: -race - rules: - - if: $CI_NIGHTLY == "develop" - <<: *build - -build:nightly: - variables: - TAG: $CI_REGISTRY_IMAGE:nightly - rules: - - if: $CI_NIGHTLY == "mainline" - <<: *build - -build:merge-request: - variables: - TAG: $CI_REGISTRY_IMAGE:merge-request - BUILDARGS: -race - rules: - - if: $CI_PIPELINE_SOURCE == "merge_request_event" - <<: *build - -build:latest: - variables: - TAG: $CI_REGISTRY_IMAGE:latest - rules: - - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_NIGHTLY == null - <<: *build \ No newline at end of file diff --git a/build/ci/.code-quality-ci.yml b/build/ci/.code-quality-ci.yml deleted file mode 100644 index eacbfe4b6495fe32fc80002a5c53b432084b3893..0000000000000000000000000000000000000000 --- a/build/ci/.code-quality-ci.yml +++ /dev/null @@ -1,15 +0,0 @@ -code-quality: - image: golangci/golangci-lint:latest-alpine - stage: test - rules: - - if: $CI_PIPELINE_SOURCE == "merge_request_event" - - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - - if: $CI_COMMIT_BRANCH == "develop" - script: - # writes golangci-lint output to gl-code-quality-report.json - - golangci-lint run --config build/ci/.golangci-config/.golangci.yml --out-format code-climate | tee gl-code-quality-report.json - artifacts: - reports: - codequality: gl-code-quality-report.json - paths: - - gl-code-quality-report.json \ No newline at end of file diff --git a/build/ci/.security-and-compliance-ci.yml b/build/ci/.security-and-compliance-ci.yml deleted file mode 100644 index 3e98b739e62763538a6e6fe0d5bcf9259b91fbbd..0000000000000000000000000000000000000000 --- a/build/ci/.security-and-compliance-ci.yml +++ /dev/null @@ -1,10 +0,0 @@ -sast: - variables: - SAST_ANALYZER_IMAGE_TAG: '2' - SAST_EXCLUDED_PATHS: spec, test, tests, tmp - SEARCH_MAX_DEPTH: '4' - -include: - - template: Security/SAST.gitlab-ci.yml - - template: Dependency-Scanning.gitlab-ci.yml - - template: Security/License-Scanning.gitlab-ci.yml diff --git a/build/ci/.terraform-ci.yml b/build/ci/.terraform-ci.yml deleted file mode 100644 index 6049f9d3f0f9dd456c7b54cd224f87f2eb23edb4..0000000000000000000000000000000000000000 --- a/build/ci/.terraform-ci.yml +++ /dev/null @@ -1,72 +0,0 @@ - -variables: - TF_ROOT: ${CI_PROJECT_DIR}/test/terraform - TF_ADDRESS: ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/terraform/state/integration - -cache: - key: integration - paths: - - ${TF_ROOT}/.terraform - -.terraform_prefab: &tf - image: registry.gitlab.com/gitlab-org/terraform-images/stable:latest - variables: - CI_DEBUG_TRACE: "false" - before_script: - - cd ${TF_ROOT} - - export TF_VAR_integration_username=terraform - - export TF_VAR_integration_access_token=${TERRAFORM_API_TOKEN} - - export TF_VAR_integration_registry=${CI_REGISTRY} - - export TF_VAR_tls_key=${DOCKER_TLS_KEY} - - export TF_VAR_tls_cert=${DOCKER_TLS_CERT} - - export TF_VAR_tls_ca_cert=${DOCKER_TLS_CA} - rules: - - if: $CI_PIPELINE_SOURCE == "merge_request_event" && ($CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == 'develop') - variables: - TF_VAR_container_tag: $CI_REGISTRY_IMAGE:merge-request - - if: $CI_COMMIT_BRANCH == "integration-test" - - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - - if: $CI_NIGHTLY - -init: - stage: .pre - script: - - gitlab-terraform init - <<: *tf - -validate: - stage: test - script: - - gitlab-terraform validate - needs: ["init"] - <<: *tf - -plan: - before_script: - - cd ${TF_ROOT} - stage: build - script: - - gitlab-terraform plan - - gitlab-terraform plan-json - artifacts: - name: plan - paths: - - ${TF_ROOT}/plan.cache - reports: - terraform: ${TF_ROOT}/plan.json - needs: ["validate"] - <<: *tf - -apply: - stage: apply - script: - - gitlab-terraform apply - dependencies: - - plan - <<: *tf - -destroy:tf: - stage: .post - script: - - gitlab-terraform destroy - <<: *tf \ No newline at end of file diff --git a/build/ci/.test.yml b/build/ci/.test.yml deleted file mode 100644 index 225356ea6656130a0737e4b8b4a7b3ee39bcd5b2..0000000000000000000000000000000000000000 --- a/build/ci/.test.yml +++ /dev/null @@ -1,48 +0,0 @@ -integration-test: - image: golang:1.16 - stage: integration-test - needs: - - job: "apply" - - job: "deploy:integration-test" - variables: - GOSDN_LOG: "nolog" - GOSDN_TEST_API_ENDPOINT: http://gosdn-$CI_COMMIT_SHA.apps.ocp.fbi.h-da.de/api - rules: - - if: $CI_NIGHTLY - when: delayed - start_in: 2 minutes - - if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH - when: delayed - start_in: 2 minutes - - if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME != $CI_DEFAULT_BRANCH - allow_failure: true - when: delayed - start_in: 2 minutes - script: - - go test -race ./test/integration -v -coverprofile=coverage.out - -.test: &test - image: golang:1.16 - stage: test - allow_failure: true - variables: - GOSDN_LOG: "nolog" - rules: - - if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH - - if: $CI_NIGHTLY - - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH - allow_failure: true - after_script: - - go tool cover -func=coverage.out - -unit-test: - script: - - go test -short -race $(go list ./... | grep -v /forks/ | grep -v /api/ | grep -v /mocks ) -v -coverprofile=coverage.out - <<: *test - -http-api-test: - script: - - cd ./nucleus - - go test -race -v -run Test_httpApi -coverprofile=coverage.out - <<: *test \ No newline at end of file diff --git a/cli/capabilities.go b/cli/capabilities.go deleted file mode 100644 index a80540d873fd52dc582ee6ec124649f64e9ad6b5..0000000000000000000000000000000000000000 --- a/cli/capabilities.go +++ /dev/null @@ -1,44 +0,0 @@ -package cli - -import ( - "code.fbi.h-da.de/cocsn/gosdn/forks/goarista/gnmi" - "code.fbi.h-da.de/cocsn/gosdn/nucleus" - "context" - "fmt" - gpb "github.com/openconfig/gnmi/proto/gnmi" - "strings" -) - -// Capabilities sends a gNMI Capabilities request to the specified target -// and prints the supported models to stdout -func Capabilities(a, u, p string) error { - cfg := gnmi.Config{ - Addr: a, - Username: u, - Password: p, - Encoding: gpb.Encoding_JSON_IETF, - } - opts := &nucleus.GnmiTransportOptions{Config: cfg} - transport, err := nucleus.NewGnmiTransport(opts) - if err != nil { - return err - } - resp, err := transport.Capabilities(context.Background()) - if err != nil { - return err - } - modelData := resp.(*gpb.CapabilityResponse).SupportedModels - b := strings.Builder{} - for _, elem := range modelData { - _, err := b.WriteString(elem.Name) - if err != nil { - return err - } - _, err = b.WriteString("\n") - if err != nil { - return err - } - } - fmt.Println(b.String()) - return nil -} diff --git a/cli/get.go b/cli/get.go deleted file mode 100644 index ccd8b25a464dab88bb3e9b57ce921524de2f16b7..0000000000000000000000000000000000000000 --- a/cli/get.go +++ /dev/null @@ -1,37 +0,0 @@ -package cli - -import ( - "code.fbi.h-da.de/cocsn/gosdn/forks/goarista/gnmi" - "code.fbi.h-da.de/cocsn/gosdn/nucleus" - "context" - gpb "github.com/openconfig/gnmi/proto/gnmi" - log "github.com/sirupsen/logrus" -) - -// Get sends a gNMI Get request to the specified target and prints the response to stdout -func Get(a, u, p string, args ...string) (*gpb.GetResponse, error) { - sbi := &nucleus.OpenConfig{} - opts := &nucleus.GnmiTransportOptions{ - Config: gnmi.Config{ - Addr: a, - Username: u, - Password: p, - Encoding: gpb.Encoding_JSON_IETF, - }, - SetNode: sbi.SetNode(), - } - t, err := nucleus.NewGnmiTransport(opts) - if err != nil { - return nil, err - } - resp, err := t.Get(context.Background(), args...) - if err != nil { - return nil, err - } - log.Debug(resp) - r, ok := resp.(*gpb.GetResponse) - if !ok { - return nil, &nucleus.ErrInvalidTypeAssertion{} - } - return r, nil -} diff --git a/cli/http.go b/cli/http.go deleted file mode 100644 index 746c4a45146a882d827ef4b58526a5e06e4ef9a3..0000000000000000000000000000000000000000 --- a/cli/http.go +++ /dev/null @@ -1,68 +0,0 @@ -package cli - -import ( - "errors" - "fmt" - log "github.com/sirupsen/logrus" - "github.com/spf13/viper" - "io/ioutil" - "net/http" - "strings" -) - -const apiRoot = "?" - -var builder *strings.Builder - -func init() { - builder = &strings.Builder{} -} - -// HTTPGet sends sends requests from the CLI to the gosdn HTTP API and processes any response data -func HTTPGet(apiEndpoint, f string, args ...string) error { - for _, p := range args { - builder.WriteString("&") - builder.WriteString(p) - } - resp, err := http.Get(apiEndpoint + apiRoot + "q=" + f + builder.String()) - if err != nil { - return err - } - builder.Reset() - switch resp.StatusCode { - case http.StatusOK: - defer resp.Body.Close() - bytes, err := ioutil.ReadAll(resp.Body) - if err != nil { - return err - } - switch f { - case "init": - pnd := string(bytes[:36]) - sbi := string(bytes[36:]) - viper.Set("CLI_PND", pnd) - viper.Set("CLI_SBI", sbi) - err := viper.WriteConfig() - if err != nil { - log.Error(err) - } - default: - fmt.Println(string(bytes)) - } - case http.StatusCreated: - defer resp.Body.Close() - bytes, err := ioutil.ReadAll(resp.Body) - if err != nil { - return err - } - uuid := string(bytes[19:55]) - viper.Set("LAST_DEVICE_UUID", uuid) - fmt.Println(string(bytes)) - default: - log.WithFields(log.Fields{ - "status code": resp.StatusCode, - }).Error("operation unsuccessful") - return errors.New(resp.Status) - } - return nil -} diff --git a/cli/init.go b/cli/init.go deleted file mode 100644 index d85e6bd00885a1c4aefea4b6766da349ccd5b8cd..0000000000000000000000000000000000000000 --- a/cli/init.go +++ /dev/null @@ -1,17 +0,0 @@ -package cli - -import ( - model "code.fbi.h-da.de/cocsn/yang-models/generated/arista" - "github.com/openconfig/ygot/ytypes" - log "github.com/sirupsen/logrus" -) - -var testSchema *ytypes.Schema - -func init() { - var err error - testSchema, err = model.Schema() - if err != nil { - log.Fatal(err) - } -} diff --git a/cli/set.go b/cli/set.go deleted file mode 100644 index 4d01d1477fd281446c3666faaf69e9a9899f7347..0000000000000000000000000000000000000000 --- a/cli/set.go +++ /dev/null @@ -1,50 +0,0 @@ -package cli - -import ( - "code.fbi.h-da.de/cocsn/gosdn/forks/goarista/gnmi" - "code.fbi.h-da.de/cocsn/gosdn/nucleus" - "code.fbi.h-da.de/cocsn/gosdn/nucleus/util/proto" - "context" - pb "google.golang.org/protobuf/proto" - "os" -) - -// Set sends a gNMI Set request to the specified target. Only one -// request per invocation supported. -func Set(a, u, p, typ string, args ...string) error { - opts := &nucleus.GnmiTransportOptions{ - Config: gnmi.Config{ - Addr: a, - Username: u, - Password: p, - }, - } - t, err := nucleus.NewGnmiTransport(opts) - if err != nil { - return err - } - - path := gnmi.SplitPath(args[0]) - req := []interface{}{ - &gnmi.Operation{ - Type: typ, - Origin: "", - Target: "", - Path: path, - Val: args[1], - }, - } - - resp, err := t.Set(context.Background(), req...) - if err != nil { - return err - } - - _, tap := os.LookupEnv("GOSDN_TAP") - if tap { - if err := proto.Write(resp.(pb.Message), "resp-set-system-config-hostname"); err != nil { - return err - } - } - return nil -} diff --git a/cli/subscribe.go b/cli/subscribe.go deleted file mode 100644 index 88379e45f8d90f892c347c2aff18861658c18bfc..0000000000000000000000000000000000000000 --- a/cli/subscribe.go +++ /dev/null @@ -1,60 +0,0 @@ -package cli - -import ( - "code.fbi.h-da.de/cocsn/gosdn/forks/goarista/gnmi" - "code.fbi.h-da.de/cocsn/gosdn/nucleus" - "context" - "fmt" - gpb "github.com/openconfig/gnmi/proto/gnmi" - log "github.com/sirupsen/logrus" - "os" - "os/signal" - "syscall" - "time" -) - -// Subscribe starts a gNMI subscriber requersting the specified paths on the target and -// logs the response to stdout. Only 'stream' mode with 'sample' operation supported. -func Subscribe(a, u, p string, sample, heartbeat int64, args ...string) error { - sbi := &nucleus.OpenConfig{} - tOpts := &nucleus.GnmiTransportOptions{ - Config: gnmi.Config{ - Addr: a, - Username: u, - Password: p, - Encoding: gpb.Encoding_JSON_IETF, - }, - SetNode: sbi.SetNode(), - RespChan: make(chan *gpb.SubscribeResponse), - } - - device, err := nucleus.NewDevice(sbi, tOpts) - if err != nil { - return err - } - - opts := &gnmi.SubscribeOptions{ - UpdatesOnly: false, - Prefix: "", - Mode: "stream", - StreamMode: "sample", - SampleInterval: uint64(sample * time.Second.Nanoseconds()), - SuppressRedundant: false, - HeartbeatInterval: uint64(heartbeat * time.Second.Nanoseconds()), - Paths: gnmi.SplitPaths(args), - Origin: "", - Target: a, - } - done := make(chan os.Signal, 1) - signal.Notify(done, syscall.SIGILL, syscall.SIGTERM) - ctx := context.WithValue(context.Background(), nucleus.CtxKeyOpts, opts) //nolint - go func() { - if err := device.Transport.Subscribe(ctx); err != nil { - log.Fatal(err) - } - }() - fmt.Println("awaiting signal") - <-done - fmt.Println("exiting") - return nil -} diff --git a/cli/target.go b/cli/target.go deleted file mode 100644 index cd35e87a352590ed8f26bdfc94583113d189cbc0..0000000000000000000000000000000000000000 --- a/cli/target.go +++ /dev/null @@ -1,95 +0,0 @@ -package cli - -import ( - "code.fbi.h-da.de/cocsn/gosdn/forks/google/gnmi" - oc "code.fbi.h-da.de/cocsn/yang-models/generated/openconfig" - "context" - pb "github.com/openconfig/gnmi/proto/gnmi" - "github.com/openconfig/goyang/pkg/yang" - "github.com/openconfig/ygot/util" - "github.com/openconfig/ygot/ygot" - log "github.com/sirupsen/logrus" - "google.golang.org/grpc" - "google.golang.org/grpc/reflection" - "net" - "reflect" -) - -type server struct { - *gnmi.Server -} - -func callback(newConfig ygot.ValidatedGoStruct) error { - // Apply the config to your device and return nil if success. return error if fails. - // - // Do something ... - return nil -} - -func newServer(model *gnmi.Model, config []byte) (*server, error) { - s, err := gnmi.NewServer(model, config, callback) - if err != nil { - return nil, err - } - return &server{Server: s}, nil -} - -// Get overrides the Get func of gnmi.Target to provide user auth. -func (s *server) Get(ctx context.Context, req *pb.GetRequest) (*pb.GetResponse, error) { - return s.Server.Get(ctx, req) -} - -// Set overrides the Set func of gnmi.Target to provide user auth. -/* -func (s *server) Set(ctx context.Context, req *pb.SetRequest) (*pb.SetResponse, error) { - msg, ok := credentials.AuthorizeUser(ctx) - if !ok { - log.Infof("denied a Set request: %v", msg) - return nil, status.Error(codes.PermissionDenied, msg) - } - log.Infof("allowed a Set request: %v", msg) - return s.Server.Set(ctx, req) -} -*/ - -// Target starts a gNMI target listening on the specified port. -func Target(bindAddr string) error { - entries := make([]*yang.Entry, 0) - for _, e := range oc.SchemaTree { - entries = append(entries, e) - } - - modelData, err := util.FindModelData(entries) - if err != nil { - return err - } - // Google stuff from here - model := gnmi.NewModel( - modelData, - reflect.TypeOf((*oc.Device)(nil)), - oc.SchemaTree["Device"], - oc.Unmarshal, - oc.ΛEnum) - - g := grpc.NewServer() - - var configData []byte - s, err := newServer(model, configData) - if err != nil { - return err - } - pb.RegisterGNMIServer(g, s) - reflection.Register(g) - - log.Infof("starting to listen on %s", bindAddr) - listen, err := net.Listen("tcp", bindAddr) - if err != nil { - return err - } - - log.Info("starting to serve") - if err := g.Serve(listen); err != nil { - return err - } - return nil -} diff --git a/cmd/addDevice.go b/cmd/addDevice.go deleted file mode 100644 index 95180504c5828c06dce7cbb713a204e3acd9275b..0000000000000000000000000000000000000000 --- a/cmd/addDevice.go +++ /dev/null @@ -1,62 +0,0 @@ -/* -Copyright © 2021 da/net research group <danet.fbi.h-da.de> -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -*/ - -package cmd - -import ( - "code.fbi.h-da.de/cocsn/gosdn/cli" - "github.com/spf13/cobra" -) - -// addDeviceCmd represents the addDevice command -var addDeviceCmd = &cobra.Command{ - Use: "add-device", - Short: "adds a device to the controller", - Long: `Adds a device to the controller. - -Device address and user credentials need to be provided -if they diverge from the default credentials.`, - RunE: func(cmd *cobra.Command, args []string) error { - return cli.HTTPGet( - apiEndpoint, - "addDevice", - "address="+address, - "password="+password, - "username="+username, - "sbi="+cliSbi, - "pnd="+cliPnd, - ) - }, -} - -func init() { - cliCmd.AddCommand(addDeviceCmd) -} diff --git a/cmd/capabilities.go b/cmd/capabilities.go deleted file mode 100644 index 437f6f25f83b62616fd72c918bd78ee45ad82fbb..0000000000000000000000000000000000000000 --- a/cmd/capabilities.go +++ /dev/null @@ -1,52 +0,0 @@ -/* -Copyright © 2021 da/net research group <danet.fbi.h-da.de> -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -*/ - -package cmd - -import ( - "code.fbi.h-da.de/cocsn/gosdn/cli" - "github.com/spf13/cobra" -) - -// capabilitiesCmd represents the capabilities command -var capabilitiesCmd = &cobra.Command{ - Use: "capabilities", - Short: "capabilities request", - Long: `Sends a gNMI Capabilities request to the specified target -and prints the supported models to stdout.`, - RunE: func(cmd *cobra.Command, args []string) error { - return cli.Capabilities(username, password, address) - }, -} - -func init() { - rootCmd.AddCommand(capabilitiesCmd) -} diff --git a/cmd/cli.go b/cmd/cli.go deleted file mode 100644 index 320c17ca84c17bafde8a2fa350e9d67e98465fb2..0000000000000000000000000000000000000000 --- a/cmd/cli.go +++ /dev/null @@ -1,58 +0,0 @@ -/* -Copyright © 2021 da/net research group <danet.fbi.h-da.de> -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -*/ - -package cmd - -import ( - "code.fbi.h-da.de/cocsn/gosdn/cli" - "github.com/spf13/cobra" -) - -var uuid string -var apiEndpoint string - -// cliCmd represents the cli command -var cliCmd = &cobra.Command{ - Use: "cli", - Short: "initialises the cli", - Long: `Initialises the CLI. The first PND UUID and SBI UUID -are written to the config file for subsequent requests.`, - RunE: func(cmd *cobra.Command, args []string) error { - return cli.HTTPGet(apiEndpoint, "init") - }, -} - -func init() { - rootCmd.AddCommand(cliCmd) - - cliCmd.PersistentFlags().StringVar(&apiEndpoint, "controller", "http://gosdn-develop.apps.ocp.fbi.h-da.de/api", "address of the controller") - -} diff --git a/cmd/cliSet.go b/cmd/cliSet.go deleted file mode 100644 index 9a79c630bed30d80c0d8438224edc42f084ff14d..0000000000000000000000000000000000000000 --- a/cmd/cliSet.go +++ /dev/null @@ -1,64 +0,0 @@ -/* -Copyright © 2021 da/net research group <danet.fbi.h-da.de> -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -*/ - -package cmd - -import ( - "code.fbi.h-da.de/cocsn/gosdn/cli" - "github.com/spf13/cobra" -) - -// cliSetCmd represents the cliSet command -var cliSetCmd = &cobra.Command{ - Use: "set", - Args: cobra.ExactArgs(2), - Short: "set a value on a device", - Long: `Set a path value for a given device. Only one path and -only one value supported for now`, - RunE: func(cmd *cobra.Command, args []string) error { - return cli.HTTPGet( - apiEndpoint, - "set", - "uuid="+uuid, - "cliSbi="+cliSbi, - "cliPnd="+cliPnd, - "path="+args[0], - "address="+address, - "value="+args[1], - ) - }, -} - -func init() { - cliCmd.AddCommand(cliSetCmd) - - cliSetCmd.Flags().StringVar(&uuid, "uuid", "", "uuid of the requested device") -} diff --git a/cmd/get.go b/cmd/get.go deleted file mode 100644 index d200f3a08d4d8116e4168886dbde25427f99fa36..0000000000000000000000000000000000000000 --- a/cmd/get.go +++ /dev/null @@ -1,53 +0,0 @@ -/* -Copyright © 2021 da/net research group <danet.fbi.h-da.de> -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -*/ - -package cmd - -import ( - "code.fbi.h-da.de/cocsn/gosdn/cli" - "github.com/spf13/cobra" -) - -// getCmd represents the get command -var getCmd = &cobra.Command{ - Use: "gosdn get", - Short: "get request", - Long: `Sends a gNMI Get request to the specified target and -prints the response to stdout`, - RunE: func(cmd *cobra.Command, args []string) error { - _, err := cli.Get(address, username, password, args...) - return err - }, -} - -func init() { - rootCmd.AddCommand(getCmd) -} diff --git a/cmd/getDevice.go b/cmd/getDevice.go deleted file mode 100644 index 2daf934073e6f69dc0f8b55971aa747c9eccec13..0000000000000000000000000000000000000000 --- a/cmd/getDevice.go +++ /dev/null @@ -1,60 +0,0 @@ -/* -Copyright © 2021 da/net research group <danet.fbi.h-da.de> -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -*/ - -package cmd - -import ( - "code.fbi.h-da.de/cocsn/gosdn/cli" - "github.com/spf13/cobra" -) - -// getDeviceCmd represents the getDevice command -var getDeviceCmd = &cobra.Command{ - Use: "get-device", - Args: cobra.ExactArgs(1), - Short: "gets device information from the controller", - Long: `Gets device information from the controller. - -Device UUID needs to be specified as positional argument.`, - RunE: func(cmd *cobra.Command, args []string) error { - return cli.HTTPGet( - apiEndpoint, - "getDevice", - "uuid="+args[0], - "sbi="+cliSbi, - "pnd="+cliPnd, - ) - }, -} - -func init() { - cliCmd.AddCommand(getDeviceCmd) -} diff --git a/cmd/getIds.go b/cmd/getIds.go deleted file mode 100644 index ec858fd9cc857369ea9ead8887ec36c2025e0a29..0000000000000000000000000000000000000000 --- a/cmd/getIds.go +++ /dev/null @@ -1,51 +0,0 @@ -/* -Copyright © 2021 da/net research group <danet.fbi.h-da.de> -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -*/ - -package cmd - -import ( - "code.fbi.h-da.de/cocsn/gosdn/cli" - "github.com/spf13/cobra" -) - -// getIdsCmd represents the getIds command -var getIdsCmd = &cobra.Command{ - Use: "get-ids", - Short: "gets device IDs from the controller", - Long: `Gets device IDs from the controller and lists them.`, - RunE: func(cmd *cobra.Command, args []string) error { - return cli.HTTPGet(apiEndpoint, "getIDs") - }, -} - -func init() { - cliCmd.AddCommand(getIdsCmd) -} diff --git a/cmd/gosdn/main.go b/cmd/gosdn/main.go index a87c9ff0e98464b7a0c8b1ede5808946d954ca4a..3298b8935b44f844c1c2b32b1ebd0232d19e9430 100644 --- a/cmd/gosdn/main.go +++ b/cmd/gosdn/main.go @@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. */ package main -import "code.fbi.h-da.de/cocsn/gosdn/cmd" +import "code.fbi.h-da.de/danet/gosdn/cmd" func main() { cmd.Execute() diff --git a/cmd/init.go b/cmd/init.go deleted file mode 100644 index 6a4b3e9bab78477c71efc80a075b3855b1a3265d..0000000000000000000000000000000000000000 --- a/cmd/init.go +++ /dev/null @@ -1,63 +0,0 @@ -/* -Copyright © 2021 da/net research group <danet.fbi.h-da.de> -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -*/ - -package cmd - -import ( - "code.fbi.h-da.de/cocsn/gosdn/cli" - "github.com/spf13/cobra" -) - -// initCmd represents the init command -var initCmd = &cobra.Command{ - Use: "init", - Short: "initialise SBI and PND", - Long: `Initialise SBI and PND and saves values to config file. - -Same as invoking "gosdn cli" without any arguments`, - RunE: func(cmd *cobra.Command, args []string) error { - return cli.HTTPGet(apiEndpoint, "init") - }, -} - -func init() { - cliCmd.AddCommand(initCmd) - - // Here you will define your flags and configuration settings. - - // Cobra supports Persistent Flags which will work for this command - // and all subcommands, e.g.: - // initCmd.PersistentFlags().String("foo", "", "A help for foo") - - // Cobra supports local flags which will only run when this command - // is called directly, e.g.: - // initCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") -} diff --git a/cmd/request.go b/cmd/request.go deleted file mode 100644 index 54dd12becaad214a2d19f36d9da6a0a2cf7ac174..0000000000000000000000000000000000000000 --- a/cmd/request.go +++ /dev/null @@ -1,63 +0,0 @@ -/* -Copyright © 2021 da/net research group <danet.fbi.h-da.de> -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -*/ - -package cmd - -import ( - "code.fbi.h-da.de/cocsn/gosdn/cli" - "github.com/spf13/cobra" -) - -// requestCmd represents the request command -var requestCmd = &cobra.Command{ - Use: "request", - Args: cobra.ExactArgs(1), - Short: "requests a path from a specified device on the controller", - Long: `Requests a path from a specified device on the controller. - -The request path is passed as positional argument.`, - RunE: func(cmd *cobra.Command, args []string) error { - return cli.HTTPGet( - apiEndpoint, - "request", - "uuid="+uuid, - "sbi="+cliSbi, - "pnd="+cliPnd, - "path="+args[0], - ) - }, -} - -func init() { - cliCmd.AddCommand(requestCmd) - - requestCmd.Flags().StringVar(&uuid, "uuid", "", "uuid of the requested device") -} diff --git a/cmd/requestAll.go b/cmd/requestAll.go deleted file mode 100644 index 11234826ed412ed507e9711b7b4af84b379c856e..0000000000000000000000000000000000000000 --- a/cmd/requestAll.go +++ /dev/null @@ -1,61 +0,0 @@ -/* -Copyright © 2021 da/net research group <danet.fbi.h-da.de> -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -*/ - -package cmd - -import ( - "code.fbi.h-da.de/cocsn/gosdn/cli" - "github.com/spf13/cobra" -) - -// requestAllCmd represents the requestAll command -var requestAllCmd = &cobra.Command{ - Use: "request-all", - Args: cobra.ExactArgs(1), - Short: "requests specified path from all devices on the controller", - Long: `Requests a path from all devices on the controller known by -the controller. - -The request path is passed as positional argument.`, - RunE: func(cmd *cobra.Command, args []string) error { - return cli.HTTPGet( - apiEndpoint, - "requestAll", - "sbi="+cliSbi, - "pnd="+cliPnd, - "path="+args[0], - ) - }, -} - -func init() { - cliCmd.AddCommand(requestAllCmd) -} diff --git a/cmd/root.go b/cmd/root.go index 61b1e153fba0a4294eb7a18ff2538186739d5143..47cbec82915ad111268370cea0dbb191b2265a7e 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -34,8 +34,10 @@ package cmd import ( "context" "os" + "path/filepath" + + "code.fbi.h-da.de/danet/gosdn" - "code.fbi.h-da.de/cocsn/gosdn/nucleus" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" @@ -43,13 +45,9 @@ import ( ) var cfgFile string -var username string -var password string -var address string var loglevel string var grpcPort string -var cliPnd string -var cliSbi string +var csbiOrchestrator string // rootCmd represents the base command when called without any subcommands var rootCmd = &cobra.Command{ @@ -60,7 +58,7 @@ for REST API calls.`, RunE: func(cmd *cobra.Command, args []string) error { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - return nucleus.Run(ctx) + return gosdn.Run(ctx) }, } @@ -77,24 +75,28 @@ func init() { cobra.OnInitialize(initConfig) rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is ./configs/gosdn.toml)") - rootCmd.PersistentFlags().StringVarP(&username, "username", "u", "admin", "username for a gnmi resource") - rootCmd.PersistentFlags().StringVarP(&password, "password", "p", "arista", "password for a gnmi resource") - rootCmd.PersistentFlags().StringVarP(&address, "address", "a", "ceos-cocsn.apps.ocp.fbi.h-da.de:6030", "address of a gnmi target") rootCmd.PersistentFlags().StringVarP(&loglevel, "log-level", "l", "", "log level 'debug' or 'trace'") - rootCmd.Flags().StringVar(&grpcPort, "grpc-port", "55055", "port for gRPC NBI") + rootCmd.Flags().StringVar(&grpcPort, "grpc-port", "", "port for gRPC NBI") + rootCmd.Flags().StringVar(&csbiOrchestrator, "csbi-orchestrator", "", "csbi orchestrator address") } +const ( + configHome string = "./configs" + configName string = "gosdn" + configType string = "toml" +) + // initConfig reads in config file and ENV variables if set. func initConfig() { if cfgFile != "" { // Use config file from the flag. viper.SetConfigFile(cfgFile) } else { - viper.AddConfigPath("./configs") + viper.AddConfigPath(configHome) viper.AddConfigPath("/usr/local/etc/gosdn/") - viper.SetConfigType("toml") - viper.SetConfigName("gosdn") + viper.SetConfigType(configType) + viper.SetConfigName(configName) } viper.AutomaticEnv() // read in environment variables that match @@ -102,11 +104,15 @@ func initConfig() { // If a config file is found, read it in. if err := viper.ReadInConfig(); err == nil { log.Debug("Using config file:", viper.ConfigFileUsed()) + } else { + ensureViperConfigFileExists() } - viper.SetDefault("socket", ":"+grpcPort) - cliPnd = viper.GetString("CLI_PND") - cliSbi = viper.GetString("CLI_SBI") + if err := viper.BindPFlags(rootCmd.Flags()); err != nil { + log.Fatal(err) + } + viper.SetDefault("socket", ":55055") + viper.SetDefault("csbi-orchestrator", "localhost:55056") ll := viper.GetString("GOSDN_LOG") if ll != "" { @@ -123,4 +129,30 @@ func initConfig() { log.SetFormatter(&log.JSONFormatter{}) log.SetReportCaller(false) } + log.WithFields(viper.AllSettings()).Debug("current viper config") +} + +func ensureFileSystemStoreExists(pathToFile string) error { + emptyString := []byte("") + err := os.WriteFile(pathToFile, emptyString, 0600) + if err != nil { + return err + } + + return nil +} + +func ensureViperConfigFileExists() { + // Viper will crash if you call 'WriteConfig()' and the file does + // not exists yet. + // Therefore we handle this case here. + // Inspired by //https://github.com/spf13/viper/issues/430#issuecomment-661945101 + configPath := filepath.Join(configHome, configName+"."+configType) + + if _, err := os.Stat(configPath); os.IsNotExist(err) { + err := ensureFileSystemStoreExists(configPath) + if err != nil { + panic(err) + } + } } diff --git a/cmd/set.go b/cmd/set.go deleted file mode 100644 index 486d9f594a7942d25aa690d5e4b970eb96816624..0000000000000000000000000000000000000000 --- a/cmd/set.go +++ /dev/null @@ -1,57 +0,0 @@ -/* -Copyright © 2021 da/net research group <danet.fbi.h-da.de> -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -*/ - -package cmd - -import ( - "code.fbi.h-da.de/cocsn/gosdn/cli" - "github.com/spf13/cobra" -) - -var typ string - -// setCmd represents the set command -var setCmd = &cobra.Command{ - Use: "set", - Short: "set request", - Long: `Sends a gNMI Set request to the specified target. Only one -request per invocation supported.`, - RunE: func(cmd *cobra.Command, args []string) error { - return cli.Set(address, username, password, typ, args...) - }, -} - -func init() { - rootCmd.AddCommand(setCmd) - - setCmd.Flags().StringVarP(&typ, "type", "t", "update", "Type of the set request. "+ - "Possible values: 'update', 'replace', and 'delete'") -} diff --git a/cmd/subscribe.go b/cmd/subscribe.go deleted file mode 100644 index a641b7fb4f4abffebd4e6848ae5cf6343644d276..0000000000000000000000000000000000000000 --- a/cmd/subscribe.go +++ /dev/null @@ -1,59 +0,0 @@ -/* -Copyright © 2021 da/net research group <danet.fbi.h-da.de> -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -*/ - -package cmd - -import ( - "code.fbi.h-da.de/cocsn/gosdn/cli" - "github.com/spf13/cobra" -) - -var sampleInterval int64 -var heartbeatInterval int64 - -// subscribeCmd represents the subscribe command -var subscribeCmd = &cobra.Command{ - Use: "subscribe", - Short: "subscribe to target", - Long: `Starts a gNMI subscriber requesting the specified paths on the target and logs the response to stdout. - -Only 'stream' mode with 'sample' operation supported.`, - RunE: func(cmd *cobra.Command, args []string) error { - return cli.Subscribe(address, username, password, sampleInterval, heartbeatInterval, args...) - }, -} - -func init() { - rootCmd.AddCommand(subscribeCmd) - - subscribeCmd.Flags().Int64Var(&sampleInterval, "sample-rate", 5, "Sample rate per second.") - subscribeCmd.Flags().Int64Var(&heartbeatInterval, "heartbeat-rate", 1, "Heartbeat rate per second.") -} diff --git a/cmd/target.go b/cmd/target.go deleted file mode 100644 index 97224d87268e43bf3edadfa9368e141efe3148d0..0000000000000000000000000000000000000000 --- a/cmd/target.go +++ /dev/null @@ -1,56 +0,0 @@ -/* -Copyright © 2021 da/net research group <danet.fbi.h-da.de> -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -*/ - -package cmd - -import ( - "code.fbi.h-da.de/cocsn/gosdn/cli" - - "github.com/spf13/cobra" -) - -var bindAddr string - -// targetCmd represents the target command -var targetCmd = &cobra.Command{ - Use: "target", - Short: "start gnmi target", - Long: `Starts a gNMI target listening on the specified port.`, - RunE: func(cmd *cobra.Command, args []string) error { - return cli.Target(bindAddr) - }, -} - -func init() { - rootCmd.AddCommand(targetCmd) - - targetCmd.Flags().StringVar(&bindAddr, "bind-address", ":9339", "listen address of the target: [address]:port") -} diff --git a/cmd/util.go b/cmd/util.go deleted file mode 100644 index cb2eeb19d92a95250edac97b53b84f9e3431c899..0000000000000000000000000000000000000000 --- a/cmd/util.go +++ /dev/null @@ -1,51 +0,0 @@ -/* -Copyright © 2021 da/net research group <danet.fbi.h-da.de> -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -*/ - -package cmd - -import ( - "errors" - "github.com/spf13/cobra" -) - -// utilCmd represents the util command -var utilCmd = &cobra.Command{ - Use: "util", - Short: "multiple ygot utils - not yet implemented", - Long: ``, - RunE: func(cmd *cobra.Command, args []string) error { - return errors.New("not implemented") - }, -} - -func init() { - ygotCmd.AddCommand(utilCmd) -} diff --git a/cmd/ygot.go b/cmd/ygot.go deleted file mode 100644 index 81ee206ba74db83bbc6e2550b6cde8fe928a9965..0000000000000000000000000000000000000000 --- a/cmd/ygot.go +++ /dev/null @@ -1,52 +0,0 @@ -/* -Copyright © 2021 da/net research group <danet.fbi.h-da.de> -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -*/ - -package cmd - -import ( - "errors" - - "github.com/spf13/cobra" -) - -// ygotCmd represents the ygot command -var ygotCmd = &cobra.Command{ - Use: "ygot", - Short: "multiple ygot utils - not yet implemented", - Long: ``, - RunE: func(cmd *cobra.Command, args []string) error { - return errors.New("not implemented") - }, -} - -func init() { - rootCmd.AddCommand(ygotCmd) -} diff --git a/config/config.go b/config/config.go new file mode 100644 index 0000000000000000000000000000000000000000..86e39b6872bd7cda753714360277a955b348d7f9 --- /dev/null +++ b/config/config.go @@ -0,0 +1,114 @@ +package config + +import ( + "os" + "time" + + "github.com/google/uuid" + "github.com/sirupsen/logrus" + log "github.com/sirupsen/logrus" + "github.com/spf13/viper" +) + +const ( + defaultTimeOutDuration10minutes = time.Minute * 10 + basePNDUUIDKey = "basePNDUUID" + baseSouthBoundTypeKey = "baseSouthBoundType" + baseSouthBoundUUIDKey = "baseSouthBoundUUID" + changeTimeoutKey = "GOSDN_CHANGE_TIMEOUT" +) + +// BasePndUUID is an uuid for the base PND +var BasePndUUID uuid.UUID + +// BaseSouthBoundType is the type of the base SBI +var BaseSouthBoundType int32 + +// BaseSouthBoundUUID is an uuid for the base SBI +var BaseSouthBoundUUID uuid.UUID + +// ChangeTimeout is the default timeout for a change +var ChangeTimeout time.Duration + +// LogLevel ist the default log level +var LogLevel logrus.Level + +// Init gets called on module import +func Init() { + InitializeConfig() +} + +// InitializeConfig loads the configuration +func InitializeConfig() error { + var err error + + basePNDUUIDFromViper, err := getUUIDFromViper(basePNDUUIDKey) + if err != nil { + return err + } + + BasePndUUID = basePNDUUIDFromViper + + baseSouthBoundUUIDFromViper, err := getUUIDFromViper(baseSouthBoundUUIDKey) + if err != nil { + return err + } + + BaseSouthBoundUUID = baseSouthBoundUUIDFromViper + + BaseSouthBoundType = viper.GetInt32(baseSouthBoundTypeKey) + if BaseSouthBoundType != 0 { + viper.Set(baseSouthBoundTypeKey, 0) + viper.WriteConfig() + } + + err = setChangeTimeout() + if err != nil { + return err + } + + setLogLevel() + + return nil +} + +func getUUIDFromViper(viperKey string) (uuid.UUID, error) { + UUIDAsString := viper.GetString(viperKey) + if UUIDAsString == "" { + newUUID := uuid.New() + viper.Set(viperKey, newUUID.String()) + viper.WriteConfig() + + return newUUID, nil + } + + parsedUUID, err := uuid.Parse(UUIDAsString) + if err != nil { + return uuid.Nil, err + } + + return parsedUUID, nil +} + +func setChangeTimeout() error { + e := os.Getenv(changeTimeoutKey) + if e != "" { + changeTimeout, err := time.ParseDuration(e) + if err != nil { + log.Fatal(err) + } + ChangeTimeout = changeTimeout + } else { + ChangeTimeout = time.Minute * 10 + } + + return nil +} + +func setLogLevel() { + if os.Getenv("GOSDN_LOG") == "nolog" { + LogLevel = logrus.PanicLevel + } else { + LogLevel = logrus.InfoLevel + } +} diff --git a/config/config_test.go b/config/config_test.go new file mode 100644 index 0000000000000000000000000000000000000000..482465dcc0f7df63b2d17096ccfb9fa58e1192d2 --- /dev/null +++ b/config/config_test.go @@ -0,0 +1,62 @@ +package config + +import ( + "os" + "testing" + "time" + + "github.com/sirupsen/logrus" + "github.com/spf13/viper" +) + +func TestInit(t *testing.T) { + viper.SetConfigFile("./config_test.toml") + viper.Set("baseSouthBoundType", 0) + viper.Set("baseSouthBoundUUID", "bf8160d4-4659-4a1b-98fd-f409a04111eb") + viper.Set("basePNDUUID", "bf8160d4-4659-4a1b-98fd-f409a04111ec") + viper.Set("GOSDN_CHANGE_TIMEOUT", "10m") +} + +func TestUseExistingConfig(t *testing.T) { + TestInit(t) + + err := InitializeConfig() + if err != nil { + t.Error(err) + return + } + + if BasePndUUID.String() != "bf8160d4-4659-4a1b-98fd-f409a04111ec" { + t.Fatalf("BasePndUUID.String() is not bf8160d4-4659-4a1b-98fd-f409a04111ec. got=%s", + BasePndUUID.String()) + } + + if BaseSouthBoundUUID.String() != "bf8160d4-4659-4a1b-98fd-f409a04111eb" { + t.Fatalf("BaseSouthBoundUUID.String() is not bf8160d4-4659-4a1b-98fd-f409a04111eb. got=%s", + BaseSouthBoundUUID.String()) + } + + if BaseSouthBoundType != 0 { + t.Fatalf("BaseSouthBoundType is not 0. got=%d", + BaseSouthBoundType) + } + + testChangeTimeout, _ := time.ParseDuration("10m") + defaultChangeTimeout := defaultTimeOutDuration10minutes + if defaultChangeTimeout != testChangeTimeout { + t.Fatalf("ChangeTimeout is not 10ms. got=%v", + ChangeTimeout) + } + + if os.Getenv("GOSDN_LOG") == "nolog" { + if LogLevel != logrus.PanicLevel { + t.Fatalf("LogLevel is not %v. got=%v", + logrus.PanicLevel, LogLevel) + } + } else { + if LogLevel != logrus.InfoLevel { + t.Fatalf("LogLevel is not %v. got=%v", + logrus.InfoLevel, LogLevel) + } + } +} diff --git a/documentation/Praxisphasen-Docs/.gitkeep b/configs/.gitkeep similarity index 100% rename from documentation/Praxisphasen-Docs/.gitkeep rename to configs/.gitkeep diff --git a/controller.go b/controller.go new file mode 100644 index 0000000000000000000000000000000000000000..81da140bfd3d49ccafa6e9c584791888eea46c4b --- /dev/null +++ b/controller.go @@ -0,0 +1,204 @@ +package gosdn + +import ( + "context" + "net" + "net/http" + "os" + "os/signal" + "sync" + "syscall" + + "github.com/google/uuid" + log "github.com/sirupsen/logrus" + "github.com/spf13/viper" + "google.golang.org/grpc" + + pb "code.fbi.h-da.de/danet/api/go/gosdn/core" + cpb "code.fbi.h-da.de/danet/api/go/gosdn/csbi" + ppb "code.fbi.h-da.de/danet/api/go/gosdn/pnd" + spb "code.fbi.h-da.de/danet/api/go/gosdn/southbound" + "code.fbi.h-da.de/danet/gosdn/config" + "code.fbi.h-da.de/danet/gosdn/interfaces/southbound" + nbi "code.fbi.h-da.de/danet/gosdn/northbound/server" + "code.fbi.h-da.de/danet/gosdn/store" + + "code.fbi.h-da.de/danet/gosdn/nucleus" +) + +var coreLock sync.RWMutex +var coreOnce sync.Once + +// Core is the representation of the controller's core +type Core struct { + pndc *store.PndStore + httpServer *http.Server + grpcServer *grpc.Server + nbi *nbi.NorthboundInterface + stopChan chan os.Signal + + csbiClient cpb.CsbiClient +} + +var c *Core + +func init() { + c = &Core{ + pndc: store.NewPndStore(), + stopChan: make(chan os.Signal, 1), + } + + // Setting up signal capturing + signal.Notify(c.stopChan, os.Interrupt, syscall.SIGTERM) +} + +// initialize does start-up housekeeping like reading controller config files +func initialize() error { + if err := startGrpc(); err != nil { + return err + } + + coreLock.Lock() + startHttpServer() + coreLock.Unlock() + + err := config.InitializeConfig() + if err != nil { + return err + } + + err = restorePrincipalNetworkDomains() + if err != nil { + return err + } + + sbi := createSouthboundInterfaces() + err = createPrincipalNetworkDomain(sbi) + if err != nil { + return err + } + + return nil +} + +func startGrpc() error { + sock := viper.GetString("socket") + lis, err := net.Listen("tcp", sock) + if err != nil { + return err + } + log.Infof("listening to %v", lis.Addr()) + c.grpcServer = grpc.NewServer() + c.nbi = nbi.NewNBI(c.pndc) + pb.RegisterCoreServer(c.grpcServer, c.nbi.Core) + ppb.RegisterPndServer(c.grpcServer, c.nbi.Pnd) + cpb.RegisterCsbiServer(c.grpcServer, c.nbi.Csbi) + go func() { + if err := c.grpcServer.Serve(lis); err != nil { + log.Fatal(err) + } + }() + + orchestrator := viper.GetString("csbi-orchestrator") + conn, err := grpc.Dial(orchestrator, grpc.WithInsecure()) + if err != nil { + log.Fatal(err) + } + c.csbiClient = cpb.NewCsbiClient(conn) + return nil +} + +// createSouthboundInterfaces initializes the controller with its supported SBIs +func createSouthboundInterfaces() southbound.SouthboundInterface { + sbi := nucleus.NewSBI(spb.Type(config.BaseSouthBoundType), config.BaseSouthBoundUUID) + + return sbi +} + +// createPrincipalNetworkDomain initializes the controller with an initial PND +func createPrincipalNetworkDomain(s southbound.SouthboundInterface) error { + if !c.pndc.Exists(config.BasePndUUID) { + pnd, err := nucleus.NewPND("base", "gosdn base pnd", config.BasePndUUID, s, c.csbiClient, callback) + if err != nil { + return err + } + err = c.pndc.Add(pnd) + if err != nil { + return err + } + return nil + } + + return nil +} + +// restorePrincipalNetworkDomains restores previously stored PNDs +func restorePrincipalNetworkDomains() error { + pndsFromStore, err := c.pndc.Load() + if err != nil { + return err + } + + sbi := createSouthboundInterfaces() + + for _, pndFromStore := range pndsFromStore { + log.Debugf("Restoring PND: %s\n", pndFromStore.Name) + newPnd, err := nucleus.NewPND( + pndFromStore.Name, + pndFromStore.Description, + pndFromStore.ID, + sbi, + c.csbiClient, + callback, + ) + if err != nil { + return err + } + + err = c.pndc.Add(newPnd) + if err != nil { + return err + } + } + + return nil +} + +// Run calls initialize to start the controller +func Run(ctx context.Context) error { + var initError error + coreOnce.Do(func() { + initError = initialize() + }) + if initError != nil { + log.WithFields(log.Fields{}).Error(initError) + return initError + } + + log.WithFields(log.Fields{}).Info("initialisation finished") + + select { + case <-c.stopChan: + return shutdown() + case <-ctx.Done(): + return shutdown() + } +} + +func shutdown() error { + log.Info("shutting down controller") + coreLock.Lock() + defer coreLock.Unlock() + c.grpcServer.GracefulStop() + return stopHttpServer() +} + +func callback(id uuid.UUID, ch chan store.DeviceDetails) { + if ch != nil { + c.pndc.AddPendingChannel(id, ch) + log.Infof("pending channel %v added", id) + } else { + c.pndc.RemovePendingChannel(id) + log.Infof("pending channel %v removed", id) + } +} diff --git a/nucleus/controller_test.go b/controller_test.go similarity index 73% rename from nucleus/controller_test.go rename to controller_test.go index 47fa1026ccc54a35ca3296ce0779fc58af856e9b..da91009aa5fc9944a1bea36b1a4b48553167a4db 100644 --- a/nucleus/controller_test.go +++ b/controller_test.go @@ -1,4 +1,4 @@ -package nucleus +package gosdn import ( "context" @@ -27,12 +27,8 @@ func TestRun(t *testing.T) { args: args{request: apiEndpoint + "/readyz"}, want: http.StatusOK, }, - { - name: "init", - args: args{request: apiEndpoint + "/api?q=init"}, - want: http.StatusOK, - }, } + ctx, cancel := context.WithCancel(context.Background()) go func() { if err := Run(ctx); err != nil { @@ -49,7 +45,7 @@ func TestRun(t *testing.T) { if !reflect.DeepEqual(got.StatusCode, tests[0].want) { t.Errorf("livez got: %v, want %v", got.StatusCode, tests[0].want) } - got, err = http.Get(tests[0].args.request) + got, err = http.Get(tests[1].args.request) if err != nil { t.Error(err) return @@ -57,14 +53,6 @@ func TestRun(t *testing.T) { if !reflect.DeepEqual(got.StatusCode, tests[1].want) { t.Errorf("readyz got: %v, want %v", got.StatusCode, tests[1].want) } - got, err = http.Get(tests[0].args.request) - if err != nil { - t.Error(err) - return - } - if !reflect.DeepEqual(got.StatusCode, tests[2].want) { - t.Errorf("api init got: %v, want %v", got.StatusCode, tests[2].want) - } }) cancel() diff --git a/database/client.go b/database/client.go deleted file mode 100644 index 10e5414835fb523e273eecb87bf011535617f955..0000000000000000000000000000000000000000 --- a/database/client.go +++ /dev/null @@ -1,359 +0,0 @@ -package database - -import ( - "errors" - "github.com/neo4j/neo4j-go-driver/neo4j" - log "github.com/sirupsen/logrus" - "github.com/spf13/viper" -) - -// Database is a database -// deprecated -type Database struct { - driver neo4j.Driver -} - -// PND is a principle network domain -type PND struct { - name string - description string - interfaces []string -} - -// NewDatabaseClient creates a database ciena -func NewDatabaseClient() Database { - uri := viper.GetString("db.socket") - username := viper.GetString("db.user") - password := viper.GetString("db.password") - encrypted := viper.GetBool("db.crypto") - driver := createDriver(uri, username, password, encrypted) - - return Database{ - driver: driver, - } -} - -// createDriver creates a neo4j.Driver instance -func createDriver(uri, username, password string, encrypted bool) neo4j.Driver { - driver, err := neo4j.NewDriver( - uri, - neo4j.BasicAuth(username, password, ""), - func(c *neo4j.Config) { - c.Encrypted = encrypted - }, - ) - - if err != nil { - log.Info("failed creating database driver:", err) - } - - return driver -} - -// createSession creates a neo4j.Session -func createSession(driver neo4j.Driver, write bool) neo4j.Session { - var sessionConfig neo4j.SessionConfig - - if write { - sessionConfig = neo4j.SessionConfig{AccessMode: neo4j.AccessModeWrite} - } else { - sessionConfig = neo4j.SessionConfig{AccessMode: neo4j.AccessModeRead} - } - - session, err := driver.NewSession(sessionConfig) - - if err != nil { - log.Info(err) - } - - return session -} - -// storePndTxFunc transaction to store a pnd in the database -func storePndTxFunc(name, description string, interfaces []string) neo4j.TransactionWork { - return func(tx neo4j.Transaction) (interface{}, error) { - query := - ` - MERGE (pnd:PND {name: $name}) - ON CREATE SET pnd.description = $description, - pnd.interfaces = $interfaces - RETURN pnd - ` - - result, err := tx.Run(query, map[string]interface{}{ - "name": name, - "description": description, - "interfaces": interfaces, - }) - - if err != nil { - //TODO: handle neo4j.isServiceUnavailable() - return nil, err - } - - if result.Next() { - return result.Record().GetByIndex(0), nil - } - - return nil, errors.New("expected a record") - } -} - -// StorePND stores the given principle network domain -func (d Database) StorePND(pnd *PND) neo4j.Node { - session := createSession(d.driver, true) - defer session.Close() - - result, err := session.WriteTransaction(storePndTxFunc(pnd.name, pnd.description, pnd.interfaces)) - if err != nil { - log.Info(err) - } - - log.Info("created/updated PND with id: ", result.(neo4j.Node).Id()) - return result.(neo4j.Node) -} - -//RemovePND removes the given principle network domain by id. -func (d Database) RemovePND(id string) {} - -//GetPNDByID gets a specific PND by the given ID. -func (d Database) GetPNDByID(id string) {} - -//GetNodesByLabel gets all nodes that belong to a specific label. -func (d Database) GetNodesByLabel(label string) {} - -//GetNodeByID gets a specific node by ID. -func (d Database) GetNodeByID(id string) {} - -//storeNodesTxFunc transaction to store devices from a json. -//relates them to a specific pnd id. -//returns a slice of added devices -func storeNodesTxFunc(json string, id int64) neo4j.TransactionWork { - return func(tx neo4j.Transaction) (interface{}, error) { - var nodelist []neo4j.Node - query := - ` - WITH apoc.convert.fromJsonMap($stringToAdd) - AS value - UNWIND value.data as d - MERGE (device:Device {id: d.object_id}) - ON CREATE SET device.nativeName = d.object_data.` + "`tapi-object-data`.name[0].value," + ` - device.deviceType = d.object_data.` + "`tapi-object-data`.name[1].value," + ` - device.serialNumber = d.object_data.` + "`tapi-object-data`.name[2].value," + ` - device.softwareVersion = d.object_data.` + "`tapi-object-data`.name[3].value," + ` - device.` + "`operational-state` = d.object_data.`tapi-object-data`.`operational-state`" + ` - WITH device - MATCH (pnd:PND) - WHERE id(pnd) = $pnd - MERGE (device)-[:BELONGS_TO]->(pnd) - RETURN device - ` - - result, err := tx.Run(query, map[string]interface{}{ - "stringToAdd": json, - "pnd": id, - }) - - if err != nil { - //TODO: handle neo4j.isServiceUnavailable() - return nil, err - } - - for result.Next() { - nodelist = append(nodelist, result.Record().GetByIndex(0).(neo4j.Node)) - } - - if err = result.Err(); err != nil { - return nil, err - } - - return nodelist, nil - } -} - -// StoreNodes stores the given nodes to the database and adds them to a -// principle networt domain (PND). It is required for a node to belong to a PND. -func (d Database) StoreNodes(json string) []neo4j.Node { - //TODO: remove this after testing and add own gRPC call for it - testPND := PND{name: "test_PND", description: "very interesting", interfaces: []string{"TAPI", "RESTCONF"}} - pnd := d.StorePND(&testPND).Id() - - session := createSession(d.driver, true) - defer session.Close() - - result, err := session.WriteTransaction(storeNodesTxFunc(json, pnd)) - if err != nil { - log.Info(err) - } - - log.Info("added/updated devices (count): ", len(result.([]neo4j.Node))) - return result.([]neo4j.Node) -} - -// RemoveNodes removes the given nodes and their relationships -func (d Database) RemoveNodes(json string) {} - -// RemoveSingleNode removes the given node and their relationship by id. -func (d Database) RemoveSingleNode(id string) {} - -// storeLinksTxFunc transaction to store links from a json. -// creates relation between different devices. -// returns a slice of those created relations. -func storeLinksTxFunc(json string) neo4j.TransactionWork { - return func(tx neo4j.Transaction) (interface{}, error) { - var relationsList []neo4j.Relationship - query := - ` - WITH apoc.convert.fromJsonMap($stringToAdd) - AS value - UNWIND value.data as l - MATCH (d:Device), (d2:Device) - WHERE d.id = l.object_data.` + "`tapi-object-data`.`node-edge-point`[0].`node-uuid`" + ` - AND d2.id = l.object_data.` + "`tapi-object-data`.`node-edge-point`[1].`node-uuid`" + ` - CALL apoc.merge.relationship(d,l.object_data.` + "`tapi-object-data`.`layer-qualifier`,{},{}, d2,{})" + ` - YIELD rel - RETURN rel - ` - - result, err := tx.Run(query, map[string]interface{}{ - "stringToAdd": json, - }) - - if err != nil { - //TODO: handle neo4j.isServiceUnavailable() - return nil, err - } - - for result.Next() { - relationsList = append(relationsList, result.Record().GetByIndex(0).(neo4j.Relationship)) - } - - if err = result.Err(); err != nil { - return nil, err - } - - return relationsList, nil - } -} - -// StoreLinks stores the links between nodes -func (d Database) StoreLinks(json string) []neo4j.Relationship { - session := createSession(d.driver, true) - defer session.Close() - - result, err := session.WriteTransaction(storeLinksTxFunc(json)) - if err != nil { - log.Info(err) - } - - log.Info("added/updated links (count): ", len(result.([]neo4j.Relationship))) - - return result.([]neo4j.Relationship) -} - -// storeNodeEdgePointsTxFunc transaction to store interfaces from a json. -// returns count of added/updated interfaces -func storeNodeEdgePointsTxFunc(json string) neo4j.TransactionWork { - return func(tx neo4j.Transaction) (interface{}, error) { - query := - ` - WITH apoc.convert.fromJsonMap($stringToAdd) - AS value - UNWIND value.data as i - MERGE (interface:Interface {id: i.object_id}) - ON CREATE SET interface.object_type =i.object_type, - interface.localId = i.object_data.` + "`tapi-object-data`.name[0].value," + ` - interface.location = i.object_data.` + "`tapi-object-data`.name[1].value," + ` - interface.` + "`containing-node` = i.object_data.`tapi-object-data`.`containing-node`" + ` - RETURN count(interface) - ` - - result, err := tx.Run(query, map[string]interface{}{ - "stringToAdd": json, - }) - - if err != nil { - //TODO: handle neo4j.isServiceUnavailable() - return nil, err - } - - if result.Next() { - return result.Record().GetByIndex(0), nil - } - - return nil, errors.New("expected a record") - } -} - -//TODO: currently this goes over each and every device/interface and adds -// a interface_of relation. -> do it only for the newly added interfaces - -// storeNodeEdgePointsRelationTxFunc transaction to create relations between interfaces and devices -// returns count of added/updated relations -func storeNodeEdgePointsRelationTxFunc() neo4j.TransactionWork { - return func(tx neo4j.Transaction) (interface{}, error) { - query := - ` - MATCH (d:Device), (i:Interface) - WHERE d.id = i.` + "`containing-node`" + ` - MERGE (i)-[r:INTERFACE_OF]->(d) - RETURN count(r) - ` - - result, err := tx.Run(query, nil) - - if err != nil { - //TODO: handle neo4j.isServiceUnavailable() - return nil, err - } - - if result.Next() { - return result.Record().GetByIndex(0), nil - } - - return nil, errors.New("expected a record") - } -} - -// StoreNodeEdgePoints stores the given node edge points (interfaces) -func (d Database) StoreNodeEdgePoints(json string) { - session := createSession(d.driver, true) - defer session.Close() - - result, err := session.WriteTransaction(storeNodeEdgePointsTxFunc(json)) - if err != nil { - log.Info(err) - } - - _, err = session.WriteTransaction(storeNodeEdgePointsRelationTxFunc()) - if err != nil { - log.Info(err) - } - - log.Info("added/updated nodeEdgePoints (count): ", result) -} - -// StoreConnections stores relations between nodes -func (d Database) StoreConnections(json string) {} - -// StoreTopology creates a new network topology node. Can also create a relation -//the new node and a existing one if desired -func StoreTopology() {} - -// RemoveTopology removes the given network topology. This includes the node itself -//aswell as the containing links and relations -func RemoveTopology() {} - -// CreateTopologyRelation creates a relation between two given topologies -func CreateTopologyRelation() {} - -// CreateLink creates a link between two network elements -func CreateLink() {} - -// RemoveLink removes a link between two network elements -func RemoveLink() {} - -// Shutdown closes the connection to the database -func (d Database) Shutdown() error { - return d.driver.Close() -} diff --git a/documentation/README.md b/documentation/README.md index a3a240d010974156e93d387d0faba4ff1ee7dc79..9cf34b5a331bff5dd4dbed0b81681d182af2ae63 100644 --- a/documentation/README.md +++ b/documentation/README.md @@ -1,27 +1,4 @@ -# Minutes +# goSDN Documentation Overview -* [2020-12-07](http://portainer.danet.fbi.h-da.de:4000/MLAkHxUCS_W4njtf2sC63Q#) - -* [2020-12-03](http://portainer.danet.fbi.h-da.de:4000/q1IPsSO0TnOyk7Mcq1S38g#) - -* [2020-11-30](http://portainer.danet.fbi.h-da.de:4000/n5W9v9p5SzWVnK_N7kDhcQ#) - -# Markdown Design Document - -Uses [pandoc](https://pandoc.org/MANUAL.html#pandocs-markdown) flavoured markdown. - -``` sh -pandoc --filter pandoc-citeproc --bibliography=bibliography.bib --csl=acm-sig-proceedings.csl --variable papersize=a4paper -s *.md -o paper.pdf -``` - -## Citation Styles - -[Citation Style Language Repository](https://github.com/citation-style-language/styles) - -## Resources - -[How to 1](https://gist.github.com/maxogden/97190db73ac19fc6c1d9beee1a6e4fc8) - -[How to 2](https://v4.chriskrycho.com/2015/academic-markdown-and-citations.html) - -[How to 3](https://medium.com/@krzysztofczarnecki/i-wrote-my-thesis-in-markdown-heres-how-it-went-3f60140dfe65) +This memo is solely the entry point to the documentation of the goSDN +controller. diff --git a/documentation/minutes/.gitkeep b/documentation/figures/.gitkeep similarity index 100% rename from documentation/minutes/.gitkeep rename to documentation/figures/.gitkeep diff --git a/documentation/figures/goSDN-Architecture-Overall.drawio b/documentation/figures/goSDN-Architecture-Overall.drawio new file mode 100644 index 0000000000000000000000000000000000000000..c5cdc0859a6a95d186050232f32d86ec6fe68cd8 --- /dev/null +++ b/documentation/figures/goSDN-Architecture-Overall.drawio @@ -0,0 +1 @@ +<mxfile host="Electron" modified="2022-02-17T14:42:51.009Z" agent="5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/16.5.1 Chrome/96.0.4664.110 Electron/16.0.7 Safari/537.36" etag="oVOpiNiALXjf1fX8wkFb" version="16.5.1" type="device"><diagram id="pwvA0ZA2h6faCE5rpLjt" name="Seite-1">7Vpbd5s4EP41fqwPd8NjTJJut23Wu845bfOmgAzayMgVIrb3168E4iaU2ElwtnuO/RI0Iw1i5ptvBoWJHa53HynYpF9JDPHEMuLdxL6cWJZpGh7/IyT7SuIHViVIKIrlpFawRP9AKTSktEAxzHsTGSGYoU1fGJEsgxHryQClZNuftiK4f9cNSOBAsIwAHkq/oZil8imsWSv/DaIkre9sekGlWYN6snySPAUx2XZE9tXEDikhrLpa70KIhfNqv1Trrp/QNhujMGPHLPj7Nt19/+E7q583/p3vpr9nn4sP0sojwIV84InlYW5vviLcrPArJrTUeD8LsdX5xLJt2zBM0BV5ifibkOXlTW3gntbimyLCsMhrBd9iZbzSSu+wfe1ySooshmLXJldvU8TgcgMiod1ykHFZytZYqjG4h3gOooekXBbK7WYkg+IhEMaqiN86bB7KXpU/Ls8ZJQ+w1sRwBYpyt5W8jr3VbLjr+NqLkDK464hkID5CsoaM7vkUqbU9CQqZFdZMjrctxswaOGkHX/U6IGGdNKbbyPMLGfwXAMHSAEGJC8ziC5FRfBRhkOcoKt0DKBuKOxFqw2k85zwY9xJx6LqOa1yNZ2oZhRgw9NhPX5275B0WBJVAryNjKZEJgqnbN5KTgkZQrusmnGpKDfLQFHdeAtnAVBnB5tFfH1T7PbJ7gYskAfcYnhO8jb3lHE5w/z3z2znndznD8UfLb/cwVZw4v91z9T6Q3AkFMYL6NbXuElHeOSKScT2PvQDhaUhhAJj/vOoHAwDdEMrSuQgGl19sNhhFoPTN03E23hrn1wbpBI2YGRwZEudUITF1LfkpmJo7je6/i8HUcaxa8KOrvdz1RvvuaAEp4k8M6f+F+NXks5UIHkv7jhlMDTtof54+qd+pBpi6IqDghb96bsTlCsOdRMh8bAy5XQSZBxA0ClhMQ4OWRvhWuJhNMZeBtYM3AEYxpWLv1BiZHcaIUlkNw/PCkIdKcCmvAfgCo0SQLyObjvSLIPYFyZGk5nvCGFnXjN9RRDzSgivmQNppBB1wcV7HKONlvD7LMZQugG8sLH+Dks81nu+bc1tTT5Qy0y0lmSh32npf58x6l4iTrWkG2ZbQh3zKM6Da+PNFbYzi5D+BwE4SzDQ5oKLrNbVp83kR5X9YNA/Db2xxu7v+8ulO8z5Ztgv3sl34JCK6Ej2ACq4D7UG/ZwQ0kueArqEDjIrINYpjcSMliKWpgnEIlrbEMOc7QFnCRw4fMQrhNcFxJTGl5Ct5bAUZ3F5xRlrWTzKbt20zbBRtJ21fdPQZQ2z/V0lDJLvSzLbCdtBhXr25Elb6tQ2Vv3hlDpM1LJv5dqE4ee1MiQr6yEPTmzGZXfKrGORpE7Qx2mNbqdDWEO7Be8L9mHfmDjqeCrhSViU/dOqvlNTB4A41Wsc/X3Z7bVtbg19adqv6czjzD5bnsZs095U1d4AltV8fr+Jq/TVsyjg5UvCheZk+k+WZLMc8S7A1Zwkzd0iWakKNRpbemSyV5D81WbqGAgHjOLIci+M0b55LcTJzbgfPDDcCw/FmQH1tdocc55tTDcudrCU0f32aa85eTk1z5jvxnGMqPOcd9w+bV/Bc4QJ/Ft1YLAcbJ7oNzD/vTM03Eude7sx0faYb0JompV7AdGbgD5jO8zTdnPV2ntNi3vpVaU5LOX2yei6JjwjKWz8gcU7VlfFh+7VYNb395s6++hc=</diagram></mxfile> \ No newline at end of file diff --git a/documentation/figures/goSDN-Architecture-sbi-concept-detail.drawio b/documentation/figures/goSDN-Architecture-sbi-concept-detail.drawio new file mode 100644 index 0000000000000000000000000000000000000000..ee2a511ccab5e69370c4a179d2ffe5fbc34d9a83 --- /dev/null +++ b/documentation/figures/goSDN-Architecture-sbi-concept-detail.drawio @@ -0,0 +1 @@ +<mxfile host="Electron" modified="2022-02-17T14:38:29.165Z" agent="5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/16.5.1 Chrome/96.0.4664.110 Electron/16.0.7 Safari/537.36" etag="cQigzejTX8Fo0TpT8GV8" version="16.5.1" type="device"><diagram id="pwvA0ZA2h6faCE5rpLjt" name="Seite-1">7Vpbd9o4EP41nNN9KMd3zGO4tE0vlG72bJO87BG2sNUIi8oiQH79SraMbVkESCBpTyEPQaML0sx8n2bGbtn92eo9BfP4CwkhbllGuGrZg5Zlmabh8X9Css4lftfKBRFFoRxUCq7QA5RCQ0oXKIRpbSAjBDM0rwsDkiQwYDUZoJQs68OmBNd/dQ4i2BBcBQA3pd9RyGJ5CqtTyj9AFMXFL5teN++ZgWKwPEkag5AsKyJ72LL7lBCWf5ut+hAL5RV6yee929K72RiFCdtnwo9/4tX1je9Mf478W9+NPyafFm/lKvcAL+SBW5aH+Xq9KeHLCr1iQrMe7+dCbLXXsmzbNgwTVEVeJP5H5GowKhaY0EI8WgQYLtKig28xXzzvldph60LllCySEIpdm7x7GSMGr+YgEL1L7mRcFrMZlt0YTCDugeAuyqb15XYTkkBxCISxKuI/3d8cyp5mHy5PGSV3sOgJ4RQsst3m8sL21mbDVcUXWoSUwVVFJA3xHpIZZHTNh8he25NOIVFhdWR7WfqYWThOXPGvYh6Qbh1tli4tz79I4x/gCJbGERS7wCS8EIjirQCDNEVBph5AWVNcsVBpTuMx5cGwBsSm6iqqcTWaKWQUYsDQfR2+OnXJXxgTlDl6YRlLsUy323bri6RkQQMo51UBpy6lGrm5FFdeBFljqcyCm6M/3aj2S6B7jBdRBCYYngFe2t5ydgPcf0l8O2d8ZyMc/2j4dndTxYnx7Z5v7x3gjigIEdTPKfoGiPLIEZGE93PbCyc8DSk0HObVb/1uw4FGhLK4J4zB5RfzOUYByHSz3c7Gc+38VCOdIBAzu3uaxDmVSUxdSH4KpuZKo+tr0Wg7jlUIbqq9g1Wtta62xpAifmJIfxfiV8FnKxbcl/Yds9s27G758fSgfqE7wOzs9heFNQ3D8/p9bjOBE45vfIFRJIDFyLwi/SxAOyYpkrCbEMbIrEBzpSPgJhd+0ANynY2g4nwcsxglnKKLPN1QGJ5vrJ99GnTOezzfN3u2hisUCqnSRCKoTMvlPBWfC9XMVpGoWrQTyJaE3qVtjpB8448T1jGIx667o2M3iaejQYPqtcdLAA+LEKUmQpDGm8u+Ym0hHwPGlZlkEsuwtZaoU1KNwnbpWuEVy8iBlosGDzejzufbj+RLeH15eXt9ez38/vZV+cc13ZrBbf+J/GNbOxY6HuH8nPz7jXy3x8n7iH78tvw0jm8/aEpGV71LfVqIkqb8eYGEylgzFIZioV5MKHrgNAfwrvvokODAr2vaamLUtk4TrmlVr0EkB8GVbAq6IxFJAB6WUgVh5ZjPRJB9ptQfkLG1LL2CBSN1lcMVYnmY4MrWTaWnDBFEY71L+bmT7/auKpYfG7czuNgbtc8yTJM7R/mVwoVDDGcwS5gUJLz5SoMYck4EDIpou5wygPeIa8ky3nwdDf5qGJ27L6vbqH5fbk+figua5s66HU46GO6Z6D+9SKK7A3VFkmPcgVoz+n8MtTmK6l+d2ornPecw9vcKY5Ur0tGUNE4Vxur9yGr4kdlwpEJxUwxXMtzs/TrVT9PQKGwjfO7zDd/Rc+7BYahvt58WiHJ9gnVl2FwMSE8SqjYfgDRZ5Q92BrUm4qi1i0NqIoozqH71+s7QDNLsszNUbOjWC1mbavXBzuC6DWYwfzVn0D06UX3hDrIglvbT3/v1gIT/vRN72Ha7K2HCwHF7Rmdb9L6prBj7xDL6EOixQEbsXeZ8plW05eHFT4J0nh90ilZiH73MGJAO76Gwicw7lAgELFOnHYhYleuK/mcfKVgtpqieuSPIcNz2yTI+Tdm1X5yba1Xkc9rc4U2QTtApUjoMp6+f0bmGoViq0/bMhrFeNKkzmw+5Guo/Zxa/XGahgt7bE/Qn8yOrmaE65/hhe/zgmU98r6IZP7hek8lfMoTY/jShXizi4JjIR+eXAuBTwbaqi+woA9XfnwA0kJe0a+j4Yyvd1zGdLbVgnJHyC18M4DtAScRbDm8xCuE7gsNcYkrJF3JfChK4rNSVB61Or3yFpCxDl2+V2BeV/oQhtv47czCSDDWjrX7ZqGBDv1zGMvq5G7AdPDOFkazTlhNFVaoyJFjQe3G1V0e0OoOW8hxsC9Vp4Lt3adT23Ab7dd2jsB9vli8h5+AoX+W2h/8D</diagram></mxfile> \ No newline at end of file diff --git a/documentation/manual b/documentation/manual new file mode 160000 index 0000000000000000000000000000000000000000..302c0bdd3648867553ac26ab3c119d5f61a04c35 --- /dev/null +++ b/documentation/manual @@ -0,0 +1 @@ +Subproject commit 302c0bdd3648867553ac26ab3c119d5f61a04c35 diff --git a/documentation/minutes/2020-09-14-minutes.md b/documentation/minutes/2020-09-14-minutes.md deleted file mode 100644 index 76e344814c1f9ce06430123f20f423f135e7adbc..0000000000000000000000000000000000000000 --- a/documentation/minutes/2020-09-14-minutes.md +++ /dev/null @@ -1,18 +0,0 @@ -# Meeting minutes 2020-09-14 - -## Project State - -### Goxobot - -v0.1.1 (r/w IP addresses and routes on *BSD) - -## Next tasks - -* Manuel: goSDN + Ciena swagger client -* Malte: Storage technologies (redis) -* Martin: Migrate Beachhead to goSDN - -### Timeline - -Late Oct: Presentation prototype for DTAG -* Read topo of Ciena devices via RESTCONF \ No newline at end of file diff --git a/documentation/minutes/2021-03-01-minutes.md b/documentation/minutes/2021-03-01-minutes.md deleted file mode 100644 index fa3616a554e7cc72bc29f43d4b9386b7d111ad46..0000000000000000000000000000000000000000 --- a/documentation/minutes/2021-03-01-minutes.md +++ /dev/null @@ -1,39 +0,0 @@ -# Agenda / Minutes - -## goSDN - -- [ ] Unit Testing -- [ ] Integration Testing - - Terraform/Docker Testumgebung -- [ ] ARCHITECTURE.md -- [ ] Wo wollen wir für 0.1.0 sein? - - abgeschlossener Testlauf im Lab / virtual Lab koennte hier sinnvoll sein (auch im Hinblick auf [MPSE](#mpse)/[OpenSource](#opensource)) - - Releasedatum Ende März - - Get/Set/Subscribe w/gNMI - -## MPSE - -- [ ] Zielsetzung -- [ ] Wo müssen wir sein, um goSDN sinnvoll für ein MPSE benutzen zu können - - Dokumentation vorantreiben um einen einfachen Einstieg zu ermöglichen. -- [ ] Potentielle Inhalte - - Controller Dashboard Web Application - -## OpenSource - -- [ ] Wo müssen wir sein, um goSDN sinnvoll OpenSource machen zu können -- [ ] Ist das mit Hinblick auf Hubraum zZ. grade überhaupt sinnvoll? - -## Telekom - -- [ ] Was brauchen wir fürs Pitch Deck/für Hubraum -- [ ] Termine - -## Offene TODOs - -- [ ] Anpassen Milestone/Epic - mk -- [ ] gRPC NBI redesign - mls/mb (nach 15.03.) - - Martin Skizziert - - Malte kommt nach Abgabe BA dazu -- [ ] Resolve ARCHITECTURE.md document - mk -- [ ] Epic für Semesterende mit Roadmap MPSE - mls diff --git a/forks/goarista/gnmi/arbitration.go b/forks/goarista/gnmi/arbitration.go deleted file mode 100644 index 78225d70240584b7e4e8b048bd833753b39ebc5e..0000000000000000000000000000000000000000 --- a/forks/goarista/gnmi/arbitration.go +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (c) 2019 Arista Networks, Inc. -// Use of this source code is governed by the Apache License 2.0 -// that can be found in the COPYING file. - -package gnmi - -import ( - "fmt" - "strconv" - "strings" - - "github.com/openconfig/gnmi/proto/gnmi_ext" -) - -// ArbitrationExt takes a string representation of a master arbitration value -// (e.g. "23", "role:42") and return a *gnmi_ext.Extension. -func ArbitrationExt(s string) (*gnmi_ext.Extension, error) { - if s == "" { - return nil, nil - } - roleID, electionID, err := parseArbitrationString(s) - if err != nil { - return nil, err - } - arb := &gnmi_ext.MasterArbitration{ - Role: &gnmi_ext.Role{Id: roleID}, - ElectionId: &gnmi_ext.Uint128{High: 0, Low: electionID}, - } - ext := gnmi_ext.Extension_MasterArbitration{MasterArbitration: arb} - return &gnmi_ext.Extension{Ext: &ext}, nil -} - -// parseArbitrationString parses the supplied string and returns the role and election id -// values. Input is of the form [<role>:]<election_id>, where election_id is a uint64. -// -// Examples: -// "1" -// "admin:42" -func parseArbitrationString(s string) (string, uint64, error) { - tokens := strings.Split(s, ":") - switch len(tokens) { - case 1: // just election id - id, err := parseElectionID(tokens[0]) - return "", id, err - case 2: // role and election id - id, err := parseElectionID(tokens[1]) - return tokens[0], id, err - } - return "", 0, fmt.Errorf("badly formed arbitration id (%s)", s) -} - -func parseElectionID(s string) (uint64, error) { - id, err := strconv.ParseUint(s, 0, 64) - if err != nil { - return 0, fmt.Errorf("badly formed arbitration id (%s)", s) - } - return id, nil -} diff --git a/forks/goarista/gnmi/arbitration_test.go b/forks/goarista/gnmi/arbitration_test.go deleted file mode 100644 index cdcc37c35b8c332f3ae4279b66ddf7b46e8b8798..0000000000000000000000000000000000000000 --- a/forks/goarista/gnmi/arbitration_test.go +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (c) 2019 Arista Networks, Inc. -// Use of this source code is governed by the Apache License 2.0 -// that can be found in the COPYING file. - -package gnmi - -import ( - "fmt" - "testing" - - "github.com/aristanetworks/goarista/test" - - "github.com/openconfig/gnmi/proto/gnmi_ext" -) - -func arbitration(role string, id *gnmi_ext.Uint128) *gnmi_ext.Extension { - arb := &gnmi_ext.MasterArbitration{ - Role: &gnmi_ext.Role{Id: role}, - ElectionId: id, - } - ext := gnmi_ext.Extension_MasterArbitration{MasterArbitration: arb} - return &gnmi_ext.Extension{Ext: &ext} -} - -func electionID(high, low uint64) *gnmi_ext.Uint128 { - return &gnmi_ext.Uint128{High: high, Low: low} -} - -func TestArbitrationExt(t *testing.T) { - testCases := map[string]struct { - s string - ext *gnmi_ext.Extension - err error - }{ - "empty": {}, - "no_role": { - s: "1", - ext: arbitration("", electionID(0, 1)), - }, - "with_role": { - s: "admin:1", - ext: arbitration("admin", electionID(0, 1)), - }, - "large_no_role": { - s: "9223372036854775807", - ext: arbitration("", electionID(0, 9223372036854775807)), - }, - "large_with_role": { - s: "admin:18446744073709551615", - ext: arbitration("admin", electionID(0, 18446744073709551615)), - }, - "invalid": { - s: "cat", - err: fmt.Errorf("badly formed arbitration id (%s)", "cat"), - }, - "invalid_too_many_colons": { - s: "dog:1:2", - err: fmt.Errorf("badly formed arbitration id (%s)", "dog:1:2"), - }, - } - - for name, tc := range testCases { - t.Run(name, func(t *testing.T) { - ext, err := ArbitrationExt(tc.s) - if !test.DeepEqual(tc.ext, ext) { - t.Errorf("Expected %#v, got %#v", tc.ext, ext) - } - if !test.DeepEqual(tc.err, err) { - t.Errorf("Expected %v, got %v", tc.err, err) - } - }) - } -} diff --git a/forks/goarista/gnmi/client.go b/forks/goarista/gnmi/client.go deleted file mode 100644 index fc041336eb078e224f739bbad9f93dd2767c10fb..0000000000000000000000000000000000000000 --- a/forks/goarista/gnmi/client.go +++ /dev/null @@ -1,286 +0,0 @@ -// Copyright (c) 2017 Arista Networks, Inc. -// Use of this source code is governed by the Apache License 2.0 -// that can be found in the COPYING file. - -package gnmi - -import ( - "context" - "crypto/tls" - "crypto/x509" - "errors" - "fmt" - "math" - "net" - "os" - - "io/ioutil" - "strings" - - "github.com/golang/protobuf/proto" - pb "github.com/openconfig/gnmi/proto/gnmi" - "google.golang.org/grpc" - "google.golang.org/grpc/credentials" - "google.golang.org/grpc/encoding/gzip" - "google.golang.org/grpc/metadata" -) - -const ( - defaultPort = "6030" - // HostnameArg is the value to be replaced by the actual hostname - HostnameArg = "HOSTNAME" -) - -// PublishFunc is the method to publish responses -type PublishFunc func(addr string, message proto.Message) - -// ParseHostnames parses a comma-separated list of names and replaces HOSTNAME with the current -// hostname in it -func ParseHostnames(list string) ([]string, error) { - items := strings.Split(list, ",") - hostname, err := os.Hostname() - if err != nil { - return nil, err - } - names := make([]string, len(items)) - for i, name := range items { - if name == HostnameArg { - name = hostname - } - names[i] = name - } - return names, nil -} - -// Config is the gnmi.Client config -type Config struct { - Addr string - CAFile string - CertFile string - KeyFile string - Password string - Username string - TLS bool - Compression string - DialOptions []grpc.DialOption - Token string - Encoding pb.Encoding -} - -// SubscribeOptions is the gNMI subscription request options -type SubscribeOptions struct { - UpdatesOnly bool - Prefix string - Mode string - StreamMode string - SampleInterval uint64 - SuppressRedundant bool - HeartbeatInterval uint64 - Paths [][]string - Origin string - Target string -} - -// accessTokenCred implements credentials.PerRPCCredentials, the gRPC -// interface for credentials that need to attach security information -// to every RPC. -type accessTokenCred struct { - bearerToken string -} - -// newAccessTokenCredential constructs a new per-RPC credential from a token. -func newAccessTokenCredential(token string) credentials.PerRPCCredentials { - bearerFmt := "Bearer %s" - return &accessTokenCred{bearerToken: fmt.Sprintf(bearerFmt, token)} -} - -func (a *accessTokenCred) GetRequestMetadata(ctx context.Context, - uri ...string) (map[string]string, error) { - authHeader := "Authorization" - return map[string]string{ - authHeader: a.bearerToken, - }, nil -} - -func (a *accessTokenCred) RequireTransportSecurity() bool { return true } - -// DialContext connects to a gnmi service and returns a client -func DialContext(ctx context.Context, cfg *Config) (pb.GNMIClient, error) { - opts := append([]grpc.DialOption(nil), cfg.DialOptions...) - - switch cfg.Compression { - case "": - case "gzip": - opts = append(opts, grpc.WithDefaultCallOptions(grpc.UseCompressor(gzip.Name))) - default: - return nil, fmt.Errorf("unsupported compression option: %q", cfg.Compression) - } - - if cfg.TLS || cfg.CAFile != "" || cfg.CertFile != "" || cfg.Token != "" { - tlsConfig := &tls.Config{ - MinVersion: tls.VersionTLS12, - } - if cfg.CAFile != "" { - b, err := ioutil.ReadFile(cfg.CAFile) - if err != nil { - return nil, err - } - cp := x509.NewCertPool() - if !cp.AppendCertsFromPEM(b) { - return nil, fmt.Errorf("credentials: failed to append certificates") - } - tlsConfig.RootCAs = cp - } else { - tlsConfig.InsecureSkipVerify = true - } - if cfg.CertFile != "" { - if cfg.KeyFile == "" { - return nil, fmt.Errorf("please provide both -certfile and -keyfile") - } - cert, err := tls.LoadX509KeyPair(cfg.CertFile, cfg.KeyFile) - if err != nil { - return nil, err - } - tlsConfig.Certificates = []tls.Certificate{cert} - } - if cfg.Token != "" { - opts = append(opts, - grpc.WithPerRPCCredentials(newAccessTokenCredential(cfg.Token))) - } - opts = append(opts, grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig))) - } else { - opts = append(opts, grpc.WithInsecure()) - } - - dial := func(ctx context.Context, addrIn string) (conn net.Conn, err error) { - var network, addr string - - split := strings.Split(addrIn, "://") - if l := len(split); l == 2 { - network = split[0] - addr = split[1] - } else { - network = "tcp" - addr = split[0] - } - - conn, err = (&net.Dialer{}).DialContext(ctx, network, addr) - return - } - - opts = append(opts, - grpc.WithContextDialer(dial), - - // Allows received protobuf messages to be larger than 4MB - grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(math.MaxInt32)), - ) - - grpcconn, err := grpc.DialContext(ctx, cfg.Addr, opts...) - if err != nil { - return nil, fmt.Errorf("failed to dial: %s", err) - } - - return pb.NewGNMIClient(grpcconn), nil -} - -// Dial connects to a gnmi service and returns a client -func Dial(cfg *Config) (pb.GNMIClient, error) { - return DialContext(context.Background(), cfg) -} - -// NewContext returns a new context with username and password -// metadata if they are set in cfg. -func NewContext(ctx context.Context, cfg *Config) context.Context { - if cfg.Username != "" { - ctx = metadata.NewOutgoingContext(ctx, metadata.Pairs( - "username", cfg.Username, - "password", cfg.Password)) - } - return ctx -} - -// NewGetRequest returns a GetRequest for the given paths -func NewGetRequest(ctx context.Context, paths [][]string, origin string) (*pb.GetRequest, error) { - val := ctx.Value("config") - cfg, ok := val.(*Config) - if !ok { - return nil, errors.New("invalid type assertion") - } - req := &pb.GetRequest{ - Path: make([]*pb.Path, len(paths)), - Encoding: cfg.Encoding, - } - for i, p := range paths { - gnmiPath, err := ParseGNMIElements(p) - if err != nil { - return nil, err - } - req.Path[i] = gnmiPath - req.Path[i].Origin = origin - } - return req, nil -} - -// NewSubscribeRequest returns a SubscribeRequest for the given paths -func NewSubscribeRequest(subscribeOptions *SubscribeOptions) (*pb.SubscribeRequest, error) { - var mode pb.SubscriptionList_Mode - switch subscribeOptions.Mode { - case "once": - mode = pb.SubscriptionList_ONCE - case "poll": - mode = pb.SubscriptionList_POLL - case "": - fallthrough - case "stream": - mode = pb.SubscriptionList_STREAM - default: - return nil, fmt.Errorf("subscribe mode (%s) invalid", subscribeOptions.Mode) - } - - var streamMode pb.SubscriptionMode - switch subscribeOptions.StreamMode { - case "on_change": - streamMode = pb.SubscriptionMode_ON_CHANGE - case "sample": - streamMode = pb.SubscriptionMode_SAMPLE - case "": - fallthrough - case "target_defined": - streamMode = pb.SubscriptionMode_TARGET_DEFINED - default: - return nil, fmt.Errorf("subscribe stream mode (%s) invalid", subscribeOptions.StreamMode) - } - - prefixPath, err := ParseGNMIElements(SplitPath(subscribeOptions.Prefix)) - if err != nil { - return nil, err - } - subList := &pb.SubscriptionList{ - Subscription: make([]*pb.Subscription, len(subscribeOptions.Paths)), - Mode: mode, - UpdatesOnly: subscribeOptions.UpdatesOnly, - Prefix: prefixPath, - } - if subscribeOptions.Target != "" { - if subList.Prefix == nil { - subList.Prefix = &pb.Path{} - } - subList.Prefix.Target = subscribeOptions.Target - } - for i, p := range subscribeOptions.Paths { - gnmiPath, err := ParseGNMIElements(p) - if err != nil { - return nil, err - } - gnmiPath.Origin = subscribeOptions.Origin - subList.Subscription[i] = &pb.Subscription{ - Path: gnmiPath, - Mode: streamMode, - SampleInterval: subscribeOptions.SampleInterval, - SuppressRedundant: subscribeOptions.SuppressRedundant, - HeartbeatInterval: subscribeOptions.HeartbeatInterval, - } - } - return &pb.SubscribeRequest{Request: &pb.SubscribeRequest_Subscribe{ - Subscribe: subList}}, nil -} diff --git a/forks/goarista/gnmi/json.go b/forks/goarista/gnmi/json.go deleted file mode 100644 index 30aacd3df8239f39dd1af90a4fca9582cff6de1c..0000000000000000000000000000000000000000 --- a/forks/goarista/gnmi/json.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) 2017 Arista Networks, Inc. -// Use of this source code is governed by the Apache License 2.0 -// that can be found in the COPYING file. - -package gnmi - -import ( - "github.com/openconfig/gnmi/proto/gnmi" -) - -// NotificationToMap converts a Notification into a map[string]interface{} -func NotificationToMap(notif *gnmi.Notification) (map[string]interface{}, error) { - m := make(map[string]interface{}, 1) - m["timestamp"] = notif.Timestamp - m["path"] = StrPath(notif.Prefix) - if len(notif.Update) != 0 { - updates := make(map[string]interface{}, len(notif.Update)) - var err error - for _, update := range notif.Update { - updates[StrPath(update.Path)] = StrUpdateVal(update) - if err != nil { - return nil, err - } - } - m["updates"] = updates - } - if len(notif.Delete) != 0 { - deletes := make([]string, len(notif.Delete)) - for i, del := range notif.Delete { - deletes[i] = StrPath(del) - } - m["deletes"] = deletes - } - return m, nil -} diff --git a/forks/goarista/gnmi/operation.go b/forks/goarista/gnmi/operation.go deleted file mode 100644 index 01005d6f0877102e4e73124238b4e7cde93fcda9..0000000000000000000000000000000000000000 --- a/forks/goarista/gnmi/operation.go +++ /dev/null @@ -1,517 +0,0 @@ -// Copyright (c) 2017 Arista Networks, Inc. -// Use of this source code is governed by the Apache License 2.0 -// that can be found in the COPYING file. - -package gnmi - -import ( - "bufio" - "bytes" - "context" - "encoding/base64" - "encoding/json" - "errors" - "fmt" - "io" - "io/ioutil" - "math" - "os" - "path" - "strconv" - "strings" - "time" - - pb "github.com/openconfig/gnmi/proto/gnmi" - "github.com/openconfig/gnmi/proto/gnmi_ext" -) - -// GetWithRequest takes a fully formed GetRequest, performs the Get, -// and displays any response. -func GetWithRequest(ctx context.Context, client pb.GNMIClient, - req *pb.GetRequest) error { - resp, err := client.Get(ctx, req) - if err != nil { - return err - } - for _, notif := range resp.Notification { - prefix := StrPath(notif.Prefix) - for _, update := range notif.Update { - fmt.Printf("%s:\n", path.Join(prefix, StrPath(update.Path))) - fmt.Println(StrUpdateVal(update)) - } - } - return nil -} - -// Get sends a GetRequest to the given server. -func Get(ctx context.Context, client pb.GNMIClient, paths [][]string, - origin string) error { - req, err := NewGetRequest(ctx, paths, origin) - if err != nil { - return err - } - return GetWithRequest(ctx, client, req) -} - -// val may be a path to a file or it may be json. First see if it is a -// file, if so return its contents, otherwise return val -func extractJSON(val string) []byte { - if jsonBytes, err := ioutil.ReadFile(val); err == nil { - return jsonBytes - } - // Best effort check if the value might a string literal, in which - // case wrap it in quotes. This is to allow a user to do: - // gnmi update ../hostname host1234 - // gnmi update ../description 'This is a description' - // instead of forcing them to quote the string: - // gnmi update ../hostname '"host1234"' - // gnmi update ../description '"This is a description"' - maybeUnquotedStringLiteral := func(s string) bool { - if s == "true" || s == "false" || s == "null" || // JSON reserved words - strings.ContainsAny(s, `"'{}[]`) { // Already quoted or is a JSON object or array - return false - } else if _, err := strconv.ParseInt(s, 0, 32); err == nil { - // Integer. Using byte size of 32 because larger integer - // types are supposed to be sent as strings in JSON. - return false - } else if _, err := strconv.ParseFloat(s, 64); err == nil { - // Float - return false - } - - return true - } - if maybeUnquotedStringLiteral(val) { - out := make([]byte, len(val)+2) - out[0] = '"' - copy(out[1:], val) - out[len(out)-1] = '"' - return out - } - return []byte(val) -} - -// StrUpdateVal will return a string representing the value within the supplied update -func StrUpdateVal(u *pb.Update) string { - if u.Value != nil { - // Backwards compatibility with pre-v0.4 gnmi - switch u.Value.Type { - case pb.Encoding_JSON, pb.Encoding_JSON_IETF: - return strJSON(u.Value.Value) - case pb.Encoding_BYTES, pb.Encoding_PROTO: - return base64.StdEncoding.EncodeToString(u.Value.Value) - case pb.Encoding_ASCII: - return string(u.Value.Value) - default: - return string(u.Value.Value) - } - } - return StrVal(u.Val) -} - -// StrVal will return a string representing the supplied value -func StrVal(val *pb.TypedValue) string { - switch v := val.GetValue().(type) { - case *pb.TypedValue_StringVal: - return v.StringVal - case *pb.TypedValue_JsonIetfVal: - return strJSON(v.JsonIetfVal) - case *pb.TypedValue_JsonVal: - return strJSON(v.JsonVal) - case *pb.TypedValue_IntVal: - return strconv.FormatInt(v.IntVal, 10) - case *pb.TypedValue_UintVal: - return strconv.FormatUint(v.UintVal, 10) - case *pb.TypedValue_BoolVal: - return strconv.FormatBool(v.BoolVal) - case *pb.TypedValue_BytesVal: - return base64.StdEncoding.EncodeToString(v.BytesVal) - case *pb.TypedValue_DecimalVal: - return strDecimal64(v.DecimalVal) - case *pb.TypedValue_FloatVal: - return strconv.FormatFloat(float64(v.FloatVal), 'g', -1, 32) - case *pb.TypedValue_LeaflistVal: - return strLeaflist(v.LeaflistVal) - case *pb.TypedValue_AsciiVal: - return v.AsciiVal - case *pb.TypedValue_AnyVal: - return v.AnyVal.String() - case *pb.TypedValue_ProtoBytes: - return base64.StdEncoding.EncodeToString(v.ProtoBytes) - default: - panic(v) - } -} - -func strJSON(inJSON []byte) string { - var ( - out bytes.Buffer - err error - ) - // Check for ',' as simple heuristic on whether to expand JSON - // onto multiple lines, or compact it to a single line. - if bytes.Contains(inJSON, []byte{','}) { - err = json.Indent(&out, inJSON, "", " ") - } else { - err = json.Compact(&out, inJSON) - } - if err != nil { - return fmt.Sprintf("(error unmarshalling json: %s)\n", err) + string(inJSON) - } - return out.String() -} - -func strDecimal64(d *pb.Decimal64) string { - var i, frac int64 - if d.Precision > 0 { - div := int64(10) - it := d.Precision - 1 - for it > 0 { - div *= 10 - it-- - } - i = d.Digits / div - frac = d.Digits % div - } else { - i = d.Digits - } - if frac < 0 { - frac = -frac - } - return fmt.Sprintf("%d.%d", i, frac) -} - -// strLeafList builds a human-readable form of a leaf-list. e.g. [1, 2, 3] or [a, b, c] -func strLeaflist(v *pb.ScalarArray) string { - var b strings.Builder - b.WriteByte('[') - - for i, elm := range v.Element { - b.WriteString(StrVal(elm)) - if i < len(v.Element)-1 { - b.WriteString(", ") - } - } - - b.WriteByte(']') - return b.String() -} - -// TypedValue marshals an interface into a gNMI TypedValue value -func TypedValue(val interface{}) *pb.TypedValue { - // TODO: handle more types: - // float64 - // maps - // key.Key - // key.Map - // ... etc - switch v := val.(type) { - case string: - return &pb.TypedValue{Value: &pb.TypedValue_StringVal{StringVal: v}} - case int: - return &pb.TypedValue{Value: &pb.TypedValue_IntVal{IntVal: int64(v)}} - case int8: - return &pb.TypedValue{Value: &pb.TypedValue_IntVal{IntVal: int64(v)}} - case int16: - return &pb.TypedValue{Value: &pb.TypedValue_IntVal{IntVal: int64(v)}} - case int32: - return &pb.TypedValue{Value: &pb.TypedValue_IntVal{IntVal: int64(v)}} - case int64: - return &pb.TypedValue{Value: &pb.TypedValue_IntVal{IntVal: v}} - case uint: - return &pb.TypedValue{Value: &pb.TypedValue_UintVal{UintVal: uint64(v)}} - case uint8: - return &pb.TypedValue{Value: &pb.TypedValue_UintVal{UintVal: uint64(v)}} - case uint16: - return &pb.TypedValue{Value: &pb.TypedValue_UintVal{UintVal: uint64(v)}} - case uint32: - return &pb.TypedValue{Value: &pb.TypedValue_UintVal{UintVal: uint64(v)}} - case uint64: - return &pb.TypedValue{Value: &pb.TypedValue_UintVal{UintVal: v}} - case bool: - return &pb.TypedValue{Value: &pb.TypedValue_BoolVal{BoolVal: v}} - case float32: - return &pb.TypedValue{Value: &pb.TypedValue_FloatVal{FloatVal: v}} - case []interface{}: - gnmiElems := make([]*pb.TypedValue, len(v)) - for i, elem := range v { - gnmiElems[i] = TypedValue(elem) - } - return &pb.TypedValue{ - Value: &pb.TypedValue_LeaflistVal{ - LeaflistVal: &pb.ScalarArray{ - Element: gnmiElems, - }}} - default: - panic(fmt.Sprintf("unexpected type %T for value %v", val, val)) - } -} - -// ExtractValue pulls a value out of a gNMI Update, parsing JSON if present. -// Possible return types: -// string -// int64 -// uint64 -// bool -// []byte -// float32 -// *gnmi.Decimal64 -// json.Number -// *any.Any -// []interface{} -// map[string]interface{} -func ExtractValue(update *pb.Update) (interface{}, error) { - var i interface{} - var err error - if update == nil { - return nil, fmt.Errorf("empty update") - } - if update.Val != nil { - i, err = extractValueV04(update.Val) - } else if update.Value != nil { - i, err = extractValueV03(update.Value) - } - return i, err -} - -func extractValueV04(val *pb.TypedValue) (interface{}, error) { - switch v := val.Value.(type) { - case *pb.TypedValue_StringVal: - return v.StringVal, nil - case *pb.TypedValue_IntVal: - return v.IntVal, nil - case *pb.TypedValue_UintVal: - return v.UintVal, nil - case *pb.TypedValue_BoolVal: - return v.BoolVal, nil - case *pb.TypedValue_BytesVal: - return v.BytesVal, nil - case *pb.TypedValue_FloatVal: - return v.FloatVal, nil - case *pb.TypedValue_DecimalVal: - return v.DecimalVal, nil - case *pb.TypedValue_LeaflistVal: - elementList := v.LeaflistVal.Element - l := make([]interface{}, len(elementList)) - for i, element := range elementList { - el, err := extractValueV04(element) - if err != nil { - return nil, err - } - l[i] = el - } - return l, nil - case *pb.TypedValue_AnyVal: - return v.AnyVal, nil - case *pb.TypedValue_JsonVal: - return decode(v.JsonVal) - case *pb.TypedValue_JsonIetfVal: - return decode(v.JsonIetfVal) - case *pb.TypedValue_AsciiVal: - return v.AsciiVal, nil - case *pb.TypedValue_ProtoBytes: - return v.ProtoBytes, nil - } - return nil, fmt.Errorf("unhandled type of value %v", val.GetValue()) -} - -func extractValueV03(val *pb.Value) (interface{}, error) { - switch val.Type { - case pb.Encoding_JSON, pb.Encoding_JSON_IETF: - return decode(val.Value) - case pb.Encoding_BYTES, pb.Encoding_PROTO: - return val.Value, nil - case pb.Encoding_ASCII: - return string(val.Value), nil - } - return nil, fmt.Errorf("unhandled type of value %v", val.GetValue()) -} - -func decode(byteArr []byte) (interface{}, error) { - decoder := json.NewDecoder(bytes.NewReader(byteArr)) - decoder.UseNumber() - var value interface{} - err := decoder.Decode(&value) - return value, err -} - -// DecimalToFloat converts a gNMI Decimal64 to a float64 -func DecimalToFloat(dec *pb.Decimal64) float64 { - return float64(dec.Digits) / math.Pow10(int(dec.Precision)) -} - -func update(p *pb.Path, val string) (*pb.Update, error) { - var v *pb.TypedValue - switch p.Origin { - case "": - v = &pb.TypedValue{ - Value: &pb.TypedValue_JsonIetfVal{JsonIetfVal: extractJSON(val)}} - case "eos_native": - v = &pb.TypedValue{ - Value: &pb.TypedValue_JsonVal{JsonVal: extractJSON(val)}} - case "cli", "test-regen-cli": - v = &pb.TypedValue{ - Value: &pb.TypedValue_AsciiVal{AsciiVal: val}} - case "p4_config": - b, err := ioutil.ReadFile(val) - if err != nil { - return nil, err - } - v = &pb.TypedValue{ - Value: &pb.TypedValue_ProtoBytes{ProtoBytes: b}} - default: - return nil, fmt.Errorf("unexpected origin: %q", p.Origin) - } - - return &pb.Update{Path: p, Val: v}, nil -} - -// Operation describes an gNMI operation. -type Operation struct { - Type string - Origin string - Target string - Path []string - Val string -} - -func newSetRequest(setOps []*Operation, exts ...*gnmi_ext.Extension) (*pb.SetRequest, error) { - req := &pb.SetRequest{} - for _, op := range setOps { - p, err := ParseGNMIElements(op.Path) - if err != nil { - return nil, err - } - p.Origin = op.Origin - - // Target must apply to the entire SetRequest. - if op.Target != "" { - req.Prefix = &pb.Path{ - Target: op.Target, - } - } - - switch op.Type { - case "delete": - req.Delete = append(req.Delete, p) - case "update": - u, err := update(p, op.Val) - if err != nil { - return nil, err - } - req.Update = append(req.Update, u) - case "replace": - u, err := update(p, op.Val) - if err != nil { - return nil, err - } - req.Replace = append(req.Replace, u) - } - } - for _, ext := range exts { - req.Extension = append(req.Extension, ext) - } - return req, nil -} - -// Set sends a SetRequest to the given client. -func Set(ctx context.Context, client pb.GNMIClient, setOps []*Operation, - exts ...*gnmi_ext.Extension) (*pb.SetResponse, error) { - req, err := newSetRequest(setOps, exts...) - if err != nil { - return nil, err - } - return client.Set(ctx, req) -} - -// Subscribe sends a SubscribeRequest to the given client. -// Deprecated: Use SubscribeErr instead. -func Subscribe(ctx context.Context, client pb.GNMIClient, subscribeOptions *SubscribeOptions, - respChan chan<- *pb.SubscribeResponse, errChan chan<- error) { - defer close(errChan) - if err := SubscribeErr(ctx, client, subscribeOptions, respChan); err != nil { - errChan <- err - } -} - -// SubscribeErr makes a gNMI.Subscribe call and writes the responses -// to the respChan. Before returning respChan will be closed. -func SubscribeErr(ctx context.Context, client pb.GNMIClient, subscribeOptions *SubscribeOptions, - respChan chan<- *pb.SubscribeResponse) error { - ctx, cancel := context.WithCancel(ctx) - defer cancel() - defer close(respChan) - - stream, err := client.Subscribe(ctx) - if err != nil { - return err - } - req, err := NewSubscribeRequest(subscribeOptions) - if err != nil { - return err - } - if err := stream.Send(req); err != nil { - return err - } - - for { - resp, err := stream.Recv() - if err != nil { - if err == io.EOF { - return nil - } - return err - } - respChan <- resp - - // For POLL subscriptions, initiate a poll request by pressing ENTER - if subscribeOptions.Mode == "poll" { - switch resp.Response.(type) { - case *pb.SubscribeResponse_SyncResponse: - fmt.Print("Press ENTER to send a poll request: ") - reader := bufio.NewReader(os.Stdin) - reader.ReadString('\n') - - pollReq := &pb.SubscribeRequest{ - Request: &pb.SubscribeRequest_Poll{ - Poll: &pb.Poll{}, - }, - } - if err := stream.Send(pollReq); err != nil { - return err - } - } - } - } -} - -// LogSubscribeResponse logs update responses to stderr. -func LogSubscribeResponse(response *pb.SubscribeResponse) error { - switch resp := response.Response.(type) { - case *pb.SubscribeResponse_Error: - return errors.New(resp.Error.Message) - case *pb.SubscribeResponse_SyncResponse: - if !resp.SyncResponse { - return errors.New("initial sync failed") - } - case *pb.SubscribeResponse_Update: - t := time.Unix(0, resp.Update.Timestamp).UTC() - prefix := StrPath(resp.Update.Prefix) - var target string - if t := resp.Update.Prefix.GetTarget(); t != "" { - target = "(" + t + ") " - } - for _, update := range resp.Update.Update { - fmt.Printf("[%s] %s%s = %s\n", t.Format(time.RFC3339Nano), - target, - path.Join(prefix, StrPath(update.Path)), - StrUpdateVal(update)) - } - for _, del := range resp.Update.Delete { - fmt.Printf("[%s] %sDeleted %s\n", t.Format(time.RFC3339Nano), - target, - path.Join(prefix, StrPath(del))) - } - } - return nil -} diff --git a/forks/goarista/gnmi/operation_test.go b/forks/goarista/gnmi/operation_test.go deleted file mode 100644 index fd575d10aa5ea2766b9da07a4c4865ee101d923c..0000000000000000000000000000000000000000 --- a/forks/goarista/gnmi/operation_test.go +++ /dev/null @@ -1,423 +0,0 @@ -// Copyright (c) 2017 Arista Networks, Inc. -// Use of this source code is governed by the Apache License 2.0 -// that can be found in the COPYING file. - -package gnmi - -import ( - "bytes" - "encoding/json" - "io/ioutil" - "os" - "testing" - - "github.com/aristanetworks/goarista/test" - "github.com/golang/protobuf/proto" - "github.com/golang/protobuf/ptypes/any" - - pb "github.com/openconfig/gnmi/proto/gnmi" -) - -func TestNewSetRequest(t *testing.T) { - pathFoo := &pb.Path{ - Element: []string{"foo"}, - Elem: []*pb.PathElem{{Name: "foo"}}, - } - pathCli := &pb.Path{ - Origin: "cli", - } - pathP4 := &pb.Path{ - Origin: "p4_config", - } - - p4FileContent := "p4_config test" - p4TestFile, err := ioutil.TempFile("", "p4TestFile") - if err != nil { - t.Errorf("cannot create test file for p4_config") - } - p4Filename := p4TestFile.Name() - - defer os.Remove(p4Filename) - - if _, err := p4TestFile.WriteString(p4FileContent); err != nil { - t.Errorf("cannot write test file for p4_config") - } - p4TestFile.Close() - - testCases := map[string]struct { - setOps []*Operation - exp pb.SetRequest - }{ - "delete": { - setOps: []*Operation{{Type: "delete", Path: []string{"foo"}}}, - exp: pb.SetRequest{Delete: []*pb.Path{pathFoo}}, - }, - "update": { - setOps: []*Operation{{Type: "update", Path: []string{"foo"}, Val: "true"}}, - exp: pb.SetRequest{ - Update: []*pb.Update{{ - Path: pathFoo, - Val: &pb.TypedValue{ - Value: &pb.TypedValue_JsonIetfVal{JsonIetfVal: []byte("true")}}, - }}, - }, - }, - "replace": { - setOps: []*Operation{{Type: "replace", Path: []string{"foo"}, Val: "true"}}, - exp: pb.SetRequest{ - Replace: []*pb.Update{{ - Path: pathFoo, - Val: &pb.TypedValue{ - Value: &pb.TypedValue_JsonIetfVal{JsonIetfVal: []byte("true")}}, - }}, - }, - }, - "cli-replace": { - setOps: []*Operation{{Type: "replace", Origin: "cli", - Val: "hostname foo\nip routing"}}, - exp: pb.SetRequest{ - Replace: []*pb.Update{{ - Path: pathCli, - Val: &pb.TypedValue{ - Value: &pb.TypedValue_AsciiVal{AsciiVal: "hostname foo\nip routing"}}, - }}, - }, - }, - "p4_config": { - setOps: []*Operation{{Type: "replace", Origin: "p4_config", - Val: p4Filename}}, - exp: pb.SetRequest{ - Replace: []*pb.Update{{ - Path: pathP4, - Val: &pb.TypedValue{ - Value: &pb.TypedValue_ProtoBytes{ProtoBytes: []byte(p4FileContent)}}, - }}, - }, - }, - "target": { - setOps: []*Operation{{Type: "replace", Target: "JPE1234567", - Path: []string{"foo"}, Val: "true"}}, - exp: pb.SetRequest{ - Prefix: &pb.Path{Target: "JPE1234567"}, - Replace: []*pb.Update{{ - Path: pathFoo, - Val: &pb.TypedValue{ - Value: &pb.TypedValue_JsonIetfVal{JsonIetfVal: []byte("true")}}, - }}, - }, - }, - } - - for name, tc := range testCases { - t.Run(name, func(t *testing.T) { - got, err := newSetRequest(tc.setOps) - if err != nil { - t.Fatal(err) - } - if diff := test.Diff(tc.exp, *got); diff != "" { - t.Errorf("unexpected diff: %s", diff) - } - }) - } -} - -func TestStrUpdateVal(t *testing.T) { - anyBytes, err := proto.Marshal(&pb.ModelData{Name: "foobar"}) - if err != nil { - t.Fatal(err) - } - anyMessage := &any.Any{TypeUrl: "gnmi/ModelData", Value: anyBytes} - anyString := proto.CompactTextString(anyMessage) - - for name, tc := range map[string]struct { - update *pb.Update - exp string - }{ - "JSON Value": { - update: &pb.Update{ - Value: &pb.Value{ - Value: []byte(`{"foo":"bar"}`), - Type: pb.Encoding_JSON}}, - exp: `{"foo":"bar"}`, - }, - "JSON_IETF Value": { - update: &pb.Update{ - Value: &pb.Value{ - Value: []byte(`{"foo":"bar"}`), - Type: pb.Encoding_JSON_IETF}}, - exp: `{"foo":"bar"}`, - }, - "BYTES Value": { - update: &pb.Update{ - Value: &pb.Value{ - Value: []byte{0xde, 0xad}, - Type: pb.Encoding_BYTES}}, - exp: "3q0=", - }, - "PROTO Value": { - update: &pb.Update{ - Value: &pb.Value{ - Value: []byte{0xde, 0xad}, - Type: pb.Encoding_PROTO}}, - exp: "3q0=", - }, - "ASCII Value": { - update: &pb.Update{ - Value: &pb.Value{ - Value: []byte("foobar"), - Type: pb.Encoding_ASCII}}, - exp: "foobar", - }, - "INVALID Value": { - update: &pb.Update{ - Value: &pb.Value{ - Value: []byte("foobar"), - Type: pb.Encoding(42)}}, - exp: "foobar", - }, - "StringVal": { - update: &pb.Update{Val: &pb.TypedValue{ - Value: &pb.TypedValue_StringVal{StringVal: "foobar"}}}, - exp: "foobar", - }, - "IntVal": { - update: &pb.Update{Val: &pb.TypedValue{ - Value: &pb.TypedValue_IntVal{IntVal: -42}}}, - exp: "-42", - }, - "UintVal": { - update: &pb.Update{Val: &pb.TypedValue{ - Value: &pb.TypedValue_UintVal{UintVal: 42}}}, - exp: "42", - }, - "BoolVal": { - update: &pb.Update{Val: &pb.TypedValue{ - Value: &pb.TypedValue_BoolVal{BoolVal: true}}}, - exp: "true", - }, - "BytesVal": { - update: &pb.Update{Val: &pb.TypedValue{ - Value: &pb.TypedValue_BytesVal{BytesVal: []byte{0xde, 0xad}}}}, - exp: "3q0=", - }, - "FloatVal": { - update: &pb.Update{Val: &pb.TypedValue{ - Value: &pb.TypedValue_FloatVal{FloatVal: 3.14}}}, - exp: "3.14", - }, - "DecimalVal": { - update: &pb.Update{Val: &pb.TypedValue{ - Value: &pb.TypedValue_DecimalVal{ - DecimalVal: &pb.Decimal64{Digits: 314, Precision: 2}, - }}}, - exp: "3.14", - }, - "LeafListVal": { - update: &pb.Update{Val: &pb.TypedValue{ - Value: &pb.TypedValue_LeaflistVal{ - LeaflistVal: &pb.ScalarArray{Element: []*pb.TypedValue{ - {Value: &pb.TypedValue_BoolVal{BoolVal: true}}, - {Value: &pb.TypedValue_AsciiVal{AsciiVal: "foobar"}}, - }}, - }}}, - exp: "[true, foobar]", - }, - "AnyVal": { - update: &pb.Update{Val: &pb.TypedValue{ - Value: &pb.TypedValue_AnyVal{AnyVal: anyMessage}}}, - exp: anyString, - }, - "JsonVal": { - update: &pb.Update{Val: &pb.TypedValue{ - Value: &pb.TypedValue_JsonVal{JsonVal: []byte(`{"foo":"bar"}`)}}}, - exp: `{"foo":"bar"}`, - }, - "JsonVal_complex": { - update: &pb.Update{Val: &pb.TypedValue{ - Value: &pb.TypedValue_JsonVal{JsonVal: []byte(`{"foo":"bar","baz":"qux"}`)}}}, - exp: `{ - "foo": "bar", - "baz": "qux" -}`, - }, - "JsonIetfVal": { - update: &pb.Update{Val: &pb.TypedValue{ - Value: &pb.TypedValue_JsonIetfVal{JsonIetfVal: []byte(`{"foo":"bar"}`)}}}, - exp: `{"foo":"bar"}`, - }, - "AsciiVal": { - update: &pb.Update{Val: &pb.TypedValue{ - Value: &pb.TypedValue_AsciiVal{AsciiVal: "foobar"}}}, - exp: "foobar", - }, - "ProtoBytes": { - update: &pb.Update{Val: &pb.TypedValue{ - Value: &pb.TypedValue_ProtoBytes{ProtoBytes: anyBytes}}}, - exp: "CgZmb29iYXI=", - }, - } { - t.Run(name, func(t *testing.T) { - got := StrUpdateVal(tc.update) - if got != tc.exp { - t.Errorf("Expected: %q Got: %q", tc.exp, got) - } - }) - } -} - -func TestTypedValue(t *testing.T) { - for tname, tcase := range map[string]struct { - in interface{} - exp *pb.TypedValue - }{ - "string": { - in: "foo", - exp: &pb.TypedValue{Value: &pb.TypedValue_StringVal{StringVal: "foo"}}, - }, - "int": { - in: 42, - exp: &pb.TypedValue{Value: &pb.TypedValue_IntVal{IntVal: 42}}, - }, - "int64": { - in: int64(42), - exp: &pb.TypedValue{Value: &pb.TypedValue_IntVal{IntVal: 42}}, - }, - "uint": { - in: uint(42), - exp: &pb.TypedValue{Value: &pb.TypedValue_UintVal{UintVal: 42}}, - }, - "bool": { - in: true, - exp: &pb.TypedValue{Value: &pb.TypedValue_BoolVal{BoolVal: true}}, - }, - "slice": { - in: []interface{}{"foo", 1, uint(2), true}, - exp: &pb.TypedValue{Value: &pb.TypedValue_LeaflistVal{LeaflistVal: &pb.ScalarArray{ - Element: []*pb.TypedValue{ - {Value: &pb.TypedValue_StringVal{StringVal: "foo"}}, - {Value: &pb.TypedValue_IntVal{IntVal: 1}}, - {Value: &pb.TypedValue_UintVal{UintVal: 2}}, - {Value: &pb.TypedValue_BoolVal{BoolVal: true}}, - }}}}, - }, - } { - t.Run(tname, func(t *testing.T) { - if got := TypedValue(tcase.in); !test.DeepEqual(got, tcase.exp) { - t.Errorf("Expected: %q Got: %q", tcase.exp, got) - } - }) - } -} - -func TestExtractJSON(t *testing.T) { - jsonFile, err := ioutil.TempFile("", "extractJSON") - if err != nil { - t.Fatal(err) - } - defer os.Remove(jsonFile.Name()) - if _, err := jsonFile.Write([]byte(`"jsonFile"`)); err != nil { - jsonFile.Close() - t.Fatal(err) - } - if err := jsonFile.Close(); err != nil { - t.Fatal(err) - } - - for val, exp := range map[string][]byte{ - jsonFile.Name(): []byte(`"jsonFile"`), - "foobar": []byte(`"foobar"`), - `"foobar"`: []byte(`"foobar"`), - "Val: true": []byte(`"Val: true"`), - "host42": []byte(`"host42"`), - "42": []byte("42"), - "-123.43": []byte("-123.43"), - "0xFFFF": []byte("0xFFFF"), - // Int larger than can fit in 32 bits should be quoted - "0x8000000000": []byte(`"0x8000000000"`), - "-0x8000000000": []byte(`"-0x8000000000"`), - "true": []byte("true"), - "false": []byte("false"), - "null": []byte("null"), - "{true: 42}": []byte("{true: 42}"), - "[]": []byte("[]"), - } { - t.Run(val, func(t *testing.T) { - got := extractJSON(val) - if !bytes.Equal(exp, got) { - t.Errorf("Unexpected diff. Expected: %q Got: %q", exp, got) - } - }) - } -} - -func TestExtractValue(t *testing.T) { - cases := []struct { - in *pb.Update - exp interface{} - }{{ - in: &pb.Update{Val: &pb.TypedValue{ - Value: &pb.TypedValue_StringVal{StringVal: "foo"}}}, - exp: "foo", - }, { - in: &pb.Update{Val: &pb.TypedValue{ - Value: &pb.TypedValue_IntVal{IntVal: 123}}}, - exp: int64(123), - }, { - in: &pb.Update{Val: &pb.TypedValue{ - Value: &pb.TypedValue_UintVal{UintVal: 123}}}, - exp: uint64(123), - }, { - in: &pb.Update{Val: &pb.TypedValue{ - Value: &pb.TypedValue_BoolVal{BoolVal: true}}}, - exp: true, - }, { - in: &pb.Update{Val: &pb.TypedValue{ - Value: &pb.TypedValue_BytesVal{BytesVal: []byte{0xde, 0xad}}}}, - exp: []byte{0xde, 0xad}, - }, { - in: &pb.Update{Val: &pb.TypedValue{ - Value: &pb.TypedValue_FloatVal{FloatVal: -12.34}}}, - exp: float32(-12.34), - }, { - in: &pb.Update{Val: &pb.TypedValue{ - Value: &pb.TypedValue_DecimalVal{DecimalVal: &pb.Decimal64{ - Digits: -1234, Precision: 2}}}}, - exp: &pb.Decimal64{Digits: -1234, Precision: 2}, - }, { - in: &pb.Update{Val: &pb.TypedValue{ - Value: &pb.TypedValue_LeaflistVal{LeaflistVal: &pb.ScalarArray{ - Element: []*pb.TypedValue{ - {Value: &pb.TypedValue_StringVal{StringVal: "foo"}}, - {Value: &pb.TypedValue_IntVal{IntVal: 123}}}}}}}, - exp: []interface{}{"foo", int64(123)}, - }, { - in: &pb.Update{Val: &pb.TypedValue{ - Value: &pb.TypedValue_JsonVal{JsonVal: []byte(`12.34`)}}}, - exp: json.Number("12.34"), - }, { - in: &pb.Update{Val: &pb.TypedValue{ - Value: &pb.TypedValue_JsonVal{JsonVal: []byte(`[12.34, 123, "foo"]`)}}}, - exp: []interface{}{json.Number("12.34"), json.Number("123"), "foo"}, - }, { - in: &pb.Update{Val: &pb.TypedValue{ - Value: &pb.TypedValue_JsonVal{JsonVal: []byte(`{"foo":"bar"}`)}}}, - exp: map[string]interface{}{"foo": "bar"}, - }, { - in: &pb.Update{Val: &pb.TypedValue{ - Value: &pb.TypedValue_JsonVal{JsonVal: []byte(`{"foo":45.67}`)}}}, - exp: map[string]interface{}{"foo": json.Number("45.67")}, - }, { - in: &pb.Update{Val: &pb.TypedValue{ - Value: &pb.TypedValue_JsonIetfVal{JsonIetfVal: []byte(`{"foo":"bar"}`)}}}, - exp: map[string]interface{}{"foo": "bar"}, - }} - for _, tc := range cases { - out, err := ExtractValue(tc.in) - if err != nil { - t.Errorf(err.Error()) - } - if !test.DeepEqual(tc.exp, out) { - t.Errorf("Extracted value is incorrect. Expected %+v, got %+v", tc.exp, out) - } - } -} diff --git a/forks/goarista/gnmi/path.go b/forks/goarista/gnmi/path.go deleted file mode 100644 index 00280a8fc5924785e036e8daf7e9e187ec8a0406..0000000000000000000000000000000000000000 --- a/forks/goarista/gnmi/path.go +++ /dev/null @@ -1,251 +0,0 @@ -// Copyright (c) 2017 Arista Networks, Inc. -// Use of this source code is governed by the Apache License 2.0 -// that can be found in the COPYING file. - -package gnmi - -import ( - "fmt" - "sort" - "strings" - - pb "github.com/openconfig/gnmi/proto/gnmi" -) - -// nextTokenIndex returns the end index of the first token. -func nextTokenIndex(path string) int { - var inBrackets bool - var escape bool - for i, c := range path { - switch c { - case '[': - inBrackets = true - escape = false - case ']': - if !escape { - inBrackets = false - } - escape = false - case '\\': - escape = !escape - case '/': - if !inBrackets && !escape { - return i - } - escape = false - default: - escape = false - } - } - return len(path) -} - -// SplitPath splits a gnmi path according to the spec. See -// https://github.com/openconfig/reference/blob/master/rpc/gnmi/gnmi-path-conventions.md -// No validation is done. Behavior is undefined if path is an invalid -// gnmi path. TODO: Do validation? -func SplitPath(path string) []string { - var result []string - if len(path) > 0 && path[0] == '/' { - path = path[1:] - } - for len(path) > 0 { - i := nextTokenIndex(path) - result = append(result, path[:i]) - path = path[i:] - if len(path) > 0 && path[0] == '/' { - path = path[1:] - } - } - return result -} - -// SplitPaths splits multiple gnmi paths -func SplitPaths(paths []string) [][]string { - out := make([][]string, len(paths)) - for i, path := range paths { - out[i] = SplitPath(path) - } - return out -} - -// StrPath builds a human-readable form of a gnmi path. -// e.g. /a/b/c[e=f] -func StrPath(path *pb.Path) string { - if path == nil { - return "/" - } else if len(path.Elem) != 0 { - return strPathV04(path) - } else if len(path.Element) != 0 { - return strPathV03(path) - } - return "/" -} - -// strPathV04 handles the v0.4 gnmi and later path.Elem member. -func strPathV04(path *pb.Path) string { - b := &strings.Builder{} - for _, elm := range path.Elem { - b.WriteRune('/') - writeSafeString(b, elm.Name, '/') - if len(elm.Key) > 0 { - // Sort the keys so that they print in a conistent - // order. We don't have the YANG AST information, so the - // best we can do is sort them alphabetically. - keys := make([]string, 0, len(elm.Key)) - for k := range elm.Key { - keys = append(keys, k) - } - sort.Strings(keys) - for _, k := range keys { - b.WriteRune('[') - b.WriteString(k) - b.WriteRune('=') - writeSafeString(b, elm.Key[k], ']') - b.WriteRune(']') - } - } - } - return b.String() -} - -// strPathV03 handles the v0.3 gnmi and earlier path.Element member. -func strPathV03(path *pb.Path) string { - return "/" + strings.Join(path.Element, "/") -} - -// upgradePath modernizes a Path by translating the contents of the Element field to Elem -func upgradePath(path *pb.Path) *pb.Path { - if len(path.Elem) == 0 { - var elems []*pb.PathElem - for _, element := range path.Element { - n, keys, _ := parseElement(element) - elems = append(elems, &pb.PathElem{Name: n, Key: keys}) - } - path.Elem = elems - path.Element = nil - } - return path -} - -// JoinPaths joins multiple gnmi paths and returns a string representation -func JoinPaths(paths ...*pb.Path) *pb.Path { - var elems []*pb.PathElem - for _, path := range paths { - path = upgradePath(path) - elems = append(elems, path.Elem...) - } - return &pb.Path{Elem: elems} -} - -func writeSafeString(b *strings.Builder, s string, esc rune) { - for _, c := range s { - if c == esc || c == '\\' { - b.WriteRune('\\') - } - b.WriteRune(c) - } -} - -// ParseGNMIElements builds up a gnmi path, from user-supplied text -func ParseGNMIElements(elms []string) (*pb.Path, error) { - var parsed []*pb.PathElem - for _, e := range elms { - n, keys, err := parseElement(e) - if err != nil { - return nil, err - } - parsed = append(parsed, &pb.PathElem{Name: n, Key: keys}) - } - return &pb.Path{ - Element: elms, // Backwards compatibility with pre-v0.4 gnmi - Elem: parsed, - }, nil -} - -// parseElement parses a path element, according to the gNMI specification. See -// https://github.com/openconfig/reference/blame/master/rpc/gnmi/gnmi-path-conventions.md -// -// It returns the first string (the current element name), and an optional map of key name -// value pairs. -func parseElement(pathElement string) (string, map[string]string, error) { - // First check if there are any keys, i.e. do we have at least one '[' in the element - name, keyStart := findUnescaped(pathElement, '[') - if keyStart < 0 { - return name, nil, nil - } - - // Error if there is no element name or if the "[" is at the beginning of the path element - if len(name) == 0 { - return "", nil, fmt.Errorf("failed to find element name in %q", pathElement) - } - - // Look at the keys now. - keys := make(map[string]string) - keyPart := pathElement[keyStart:] - for keyPart != "" { - k, v, nextKey, err := parseKey(keyPart) - if err != nil { - return "", nil, err - } - keys[k] = v - keyPart = nextKey - } - return name, keys, nil -} - -// parseKey returns the key name, key value and the remaining string to be parsed, -func parseKey(s string) (string, string, string, error) { - if s[0] != '[' { - return "", "", "", fmt.Errorf("failed to find opening '[' in %q", s) - } - k, iEq := findUnescaped(s[1:], '=') - if iEq < 0 { - return "", "", "", fmt.Errorf("failed to find '=' in %q", s) - } - if k == "" { - return "", "", "", fmt.Errorf("failed to find key name in %q", s) - } - - rhs := s[1+iEq+1:] - v, iClosBr := findUnescaped(rhs, ']') - if iClosBr < 0 { - return "", "", "", fmt.Errorf("failed to find ']' in %q", s) - } - if v == "" { - return "", "", "", fmt.Errorf("failed to find key value in %q", s) - } - - next := rhs[iClosBr+1:] - return k, v, next, nil -} - -// findUnescaped will return the index of the first unescaped match of 'find', and the unescaped -// string leading up to it. -func findUnescaped(s string, find byte) (string, int) { - // Take a fast track if there are no escape sequences - if strings.IndexByte(s, '\\') == -1 { - i := strings.IndexByte(s, find) - if i < 0 { - return s, -1 - } - return s[:i], i - } - - // Find the first match, taking care of escaped chars. - var b strings.Builder - var i int - len := len(s) - for i = 0; i < len; { - ch := s[i] - if ch == find { - return b.String(), i - } else if ch == '\\' && i < len-1 { - i++ - ch = s[i] - } - b.WriteByte(ch) - i++ - } - return b.String(), -1 -} diff --git a/forks/goarista/gnmi/path_test.go b/forks/goarista/gnmi/path_test.go deleted file mode 100644 index 27318b65c10a64949326995b727347d3f5de211a..0000000000000000000000000000000000000000 --- a/forks/goarista/gnmi/path_test.go +++ /dev/null @@ -1,308 +0,0 @@ -// Copyright (c) 2017 Arista Networks, Inc. -// Use of this source code is governed by the Apache License 2.0 -// that can be found in the COPYING file. - -package gnmi - -import ( - "fmt" - "testing" - - "github.com/aristanetworks/goarista/test" - - pb "github.com/openconfig/gnmi/proto/gnmi" -) - -func p(s ...string) []string { - return s -} - -func TestSplitPath(t *testing.T) { - for i, tc := range []struct { - in string - exp []string - }{{ - in: "/foo/bar", - exp: p("foo", "bar"), - }, { - in: "/foo/bar/", - exp: p("foo", "bar"), - }, { - in: "//foo//bar//", - exp: p("", "foo", "", "bar", ""), - }, { - in: "/foo[name=///]/bar", - exp: p("foo[name=///]", "bar"), - }, { - in: `/foo[name=[\\\]/]/bar`, - exp: p(`foo[name=[\\\]/]`, "bar"), - }, { - in: `/foo[name=[\\]/bar`, - exp: p(`foo[name=[\\]`, "bar"), - }, { - in: "/foo[a=1][b=2]/bar", - exp: p("foo[a=1][b=2]", "bar"), - }, { - in: "/foo[a=1\\]2][b=2]/bar", - exp: p("foo[a=1\\]2][b=2]", "bar"), - }, { - in: "/foo[a=1][b=2]/bar\\baz", - exp: p("foo[a=1][b=2]", "bar\\baz"), - }} { - got := SplitPath(tc.in) - if !test.DeepEqual(tc.exp, got) { - t.Errorf("[%d] unexpect split for %q. Expected: %v, Got: %v", - i, tc.in, tc.exp, got) - } - } -} - -func TestStrPath(t *testing.T) { - for i, tc := range []struct { - path string - }{{ - path: "/", - }, { - path: "/foo/bar", - }, { - path: "/foo[name=a]/bar", - }, { - path: "/foo[a=1][b=2]/bar", - }, { - path: "/foo[a=1\\]2][b=2]/bar", - }, { - path: "/foo[a=1][b=2]/bar\\/baz", - }} { - sElms := SplitPath(tc.path) - pbPath, err := ParseGNMIElements(sElms) - if err != nil { - t.Errorf("failed to parse %s: %s", sElms, err) - } - s := StrPath(pbPath) - if !test.DeepEqual(tc.path, s) { - t.Errorf("[%d] want %s, got %s", i, tc.path, s) - } - } -} - -func TestStrPathBackwardsCompat(t *testing.T) { - for i, tc := range []struct { - path *pb.Path - str string - }{{ - path: &pb.Path{ - Element: p("foo[a=1][b=2]", "bar"), - }, - str: "/foo[a=1][b=2]/bar", - }} { - got := StrPath(tc.path) - if got != tc.str { - t.Errorf("[%d] want %q, got %q", i, tc.str, got) - } - } -} - -func TestParseElement(t *testing.T) { - // test cases - cases := []struct { - // name is the name of the test useful if you want to run a single test - // from the command line -run TestParseElement/<name> - name string - // in is the path element to be parsed - in string - // fieldName is field name (YANG node name) expected to be parsed from the path element. - // Normally this is simply the path element, or if the path element contains keys this is - // the text before the first [ - fieldName string - // keys is a map of the expected key value pairs from within the []s in the - // `path element. - // - // For example prefix[ip-prefix=10.0.0.0/24][masklength-range=26..28] - // fieldName would be "prefix" - // keys would be {"ip-prefix": "10.0.0.0/24", "masklength-range": "26..28"} - keys map[string]string - // expectedError is the exact error we expect. - expectedError error - }{{ - name: "no_elms", - in: "hello", - fieldName: "hello", - }, { - name: "single_open", - in: "[", - expectedError: fmt.Errorf("failed to find element name in %q", "["), - }, { - name: "no_equal_no_close", - in: "hello[there", - expectedError: fmt.Errorf("failed to find '=' in %q", "[there"), - }, { - name: "no_equals", - in: "hello[there]", - expectedError: fmt.Errorf("failed to find '=' in %q", "[there]"), - }, { - name: "no_left_side", - in: "hello[=there]", - expectedError: fmt.Errorf("failed to find key name in %q", "[=there]"), - }, { - name: "no_right_side", - in: "hello[there=]", - expectedError: fmt.Errorf("failed to find key value in %q", "[there=]"), - }, { - name: "hanging_escape", - in: "hello[there\\", - expectedError: fmt.Errorf("failed to find '=' in %q", "[there\\"), - }, { - name: "single_name_value", - in: "hello[there=where]", - fieldName: "hello", - keys: map[string]string{"there": "where"}, - }, { - name: "single_value_with=", - in: "hello[there=whe=r=e]", - fieldName: "hello", - keys: map[string]string{"there": "whe=r=e"}, - }, { - name: "single_value_with=_and_escaped_]", - in: `hello[there=whe=\]r=e]`, - fieldName: "hello", - keys: map[string]string{"there": `whe=]r=e`}, - }, { - name: "single_value_with[", - in: "hello[there=w[[here]", - fieldName: "hello", - keys: map[string]string{"there": "w[[here"}, - }, { - name: "value_single_open", - in: "hello[first=value][", - expectedError: fmt.Errorf("failed to find '=' in %q", "["), - }, { - name: "value_no_close", - in: "hello[there=where][somename", - expectedError: fmt.Errorf("failed to find '=' in %q", "[somename"), - }, { - name: "value_no_equals", - in: "hello[there=where][somename]", - expectedError: fmt.Errorf("failed to find '=' in %q", "[somename]"), - }, { - name: "no_left_side", - in: "hello[there=where][=somevalue]", - expectedError: fmt.Errorf("failed to find key name in %q", "[=somevalue]"), - }, { - name: "no_right_side", - in: "hello[there=where][somename=]", - expectedError: fmt.Errorf("failed to find key value in %q", "[somename=]"), - }, { - name: "two_name_values", - in: "hello[there=where][somename=somevalue]", - fieldName: "hello", - keys: map[string]string{"there": "where", "somename": "somevalue"}, - }, { - name: "three_name_values", - in: "hello[there=where][somename=somevalue][anothername=value]", - fieldName: "hello", - keys: map[string]string{"there": "where", "somename": "somevalue", - "anothername": "value"}, - }, { - name: "aserisk_value", - in: "hello[there=*][somename=somevalue][anothername=value]", - fieldName: "hello", - keys: map[string]string{"there": "*", "somename": "somevalue", - "anothername": "value"}, - }} - - for _, tc := range cases { - t.Run(tc.name, func(t *testing.T) { - fieldName, keys, err := parseElement(tc.in) - if !test.DeepEqual(tc.expectedError, err) { - t.Fatalf("[%s] expected err %#v, got %#v", tc.name, tc.expectedError, err) - } - if !test.DeepEqual(tc.keys, keys) { - t.Fatalf("[%s] expected output %#v, got %#v", tc.name, tc.keys, keys) - } - if tc.fieldName != fieldName { - t.Fatalf("[%s] expected field name %s, got %s", tc.name, tc.fieldName, fieldName) - } - }) - } -} - -func strToPath(pathStr string) *pb.Path { - splitPath := SplitPath(pathStr) - path, _ := ParseGNMIElements(splitPath) - path.Element = nil - return path -} - -func strsToPaths(pathStrs []string) []*pb.Path { - var paths []*pb.Path - for _, splitPath := range SplitPaths(pathStrs) { - path, _ := ParseGNMIElements(splitPath) - path.Element = nil - paths = append(paths, path) - } - return paths -} - -func TestJoinPath(t *testing.T) { - cases := []struct { - paths []*pb.Path - exp string - }{{ - paths: strsToPaths([]string{"/foo/bar", "/baz/qux"}), - exp: "/foo/bar/baz/qux", - }, - { - paths: strsToPaths([]string{ - "/foo/bar[somekey=someval][otherkey=otherval]", "/baz/qux"}), - exp: "/foo/bar[otherkey=otherval][somekey=someval]/baz/qux", - }, - { - paths: strsToPaths([]string{ - "/foo/bar[somekey=someval][otherkey=otherval]", - "/baz/qux[somekey=someval][otherkey=otherval]"}), - exp: "/foo/bar[otherkey=otherval][somekey=someval]/" + - "baz/qux[otherkey=otherval][somekey=someval]", - }, - { - paths: []*pb.Path{ - {Element: []string{"foo", "bar[somekey=someval][otherkey=otherval]"}}, - {Element: []string{"baz", "qux[somekey=someval][otherkey=otherval]"}}}, - exp: "/foo/bar[somekey=someval][otherkey=otherval]/" + - "baz/qux[somekey=someval][otherkey=otherval]", - }, - } - - for _, tc := range cases { - got := JoinPaths(tc.paths...) - exp := strToPath(tc.exp) - exp.Element = nil - if !test.DeepEqual(got, exp) { - t.Fatalf("ERROR!\n Got: %s,\n Want %s\n", got, exp) - } - } -} - -func BenchmarkPathElementToSigleElementName(b *testing.B) { - for i := 0; i < b.N; i++ { - _, _, _ = parseElement("hello") - } -} - -func BenchmarkPathElementTwoKeys(b *testing.B) { - for i := 0; i < b.N; i++ { - _, _, _ = parseElement("hello[hello=world][bye=moon]") - } -} - -func BenchmarkPathElementBadKeys(b *testing.B) { - for i := 0; i < b.N; i++ { - _, _, _ = parseElement("hello[hello=world][byemoon]") - } -} - -func BenchmarkPathElementMaxKeys(b *testing.B) { - for i := 0; i < b.N; i++ { - _, _, _ = parseElement("hello[name=firstName][name=secondName][name=thirdName]" + - "[name=fourthName][name=fifthName][name=sixthName]") - } -} diff --git a/forks/google/gnmi/model.go b/forks/google/gnmi/model.go deleted file mode 100644 index 8d6a4998be62fba77ec2b50ea7decfb8b989fb75..0000000000000000000000000000000000000000 --- a/forks/google/gnmi/model.go +++ /dev/null @@ -1,128 +0,0 @@ -/* Copyright 2017 Google Inc. - -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 - - https://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. -*/ - -package gnmi - -import ( - oc "code.fbi.h-da.de/cocsn/yang-models/generated/arista" - "errors" - "fmt" - log "github.com/sirupsen/logrus" - "net" - "reflect" - "sort" - - "github.com/openconfig/goyang/pkg/yang" - "github.com/openconfig/ygot/ygot" - "github.com/openconfig/ygot/ytypes" - - pb "github.com/openconfig/gnmi/proto/gnmi" -) - -// JSONUnmarshaler is the signature of the Unmarshal() function in the GoStruct code generated by openconfig ygot library. -type JSONUnmarshaler func([]byte, ygot.GoStruct, ...ytypes.UnmarshalOpt) error - -// GoStructEnumData is the data type to maintain GoStruct enum type. -type GoStructEnumData map[string]map[int64]ygot.EnumDefinition - -// Model contains the model data and GoStruct information for the device to config. -type Model struct { - modelData []*pb.ModelData - structRootType reflect.Type - schemaTreeRoot *yang.Entry - jsonUnmarshaler JSONUnmarshaler - enumData GoStructEnumData -} - -// NewModel returns an instance of Model struct. -func NewModel(m []*pb.ModelData, t reflect.Type, r *yang.Entry, f JSONUnmarshaler, e GoStructEnumData) *Model { - return &Model{ - modelData: m, - structRootType: t, - schemaTreeRoot: r, - jsonUnmarshaler: f, - enumData: e, - } -} - -func (m *Model) newRootValue() interface{} { - return reflect.New(m.structRootType.Elem()).Interface() -} - -// NewConfigStruct creates a ValidatedGoStruct of this model from jsonConfig. If jsonConfig is nil, creates an empty GoStruct. -func (m *Model) NewConfigStruct(jsonConfig []byte) (ygot.ValidatedGoStruct, error) { - rootStruct, ok := m.newRootValue().(ygot.ValidatedGoStruct) - if !ok { - return nil, errors.New("root node is not a ygot.ValidatedGoStruct") - } - ifaces, err := getInterfaces() - if err != nil { - return nil, err - } - device, ok := rootStruct.(*oc.Device) - if !ok { - return nil, errors.New("root node is not a oc.Device") - } - device.Interfaces = ifaces - return device, nil -} - -// SupportedModels returns a list of supported models. -func (m *Model) SupportedModels() []string { - mDesc := make([]string, len(m.modelData)) - for i, m := range m.modelData { - mDesc[i] = fmt.Sprintf("%s %s", m.Name, m.Version) - } - sort.Strings(mDesc) - return mDesc -} - -func getInterfaces() (*oc.OpenconfigInterfaces_Interfaces, error) { - ifaces, err := net.Interfaces() - if err != nil { - log.Fatal() - } - interfaces := &oc.OpenconfigInterfaces_Interfaces{ - Interface: make(map[string]*oc.OpenconfigInterfaces_Interfaces_Interface), - } - - for _, tInterface := range ifaces { - var mtu *uint16 - var name *string - var index *uint32 - - rmtu := uint16(tInterface.MTU) - rname := tInterface.Name - rindex := uint32(tInterface.Index) - - mtu = &rmtu - name = &rname - index = &rindex - - iface, err := interfaces.NewInterface(tInterface.Name) - if err != nil { - return nil, err - } - iface.State = &oc.OpenconfigInterfaces_Interfaces_Interface_State{ - Ifindex: &rindex, - Mtu: &rmtu, - Name: &rname, - } - iface.State.Name = name - iface.State.Mtu = mtu - iface.State.Ifindex = index - } - return interfaces, nil -} diff --git a/forks/google/gnmi/server.go b/forks/google/gnmi/server.go deleted file mode 100644 index 2f9416149ea5b861078378049a4e3a416b7bde7c..0000000000000000000000000000000000000000 --- a/forks/google/gnmi/server.go +++ /dev/null @@ -1,602 +0,0 @@ -/* Copyright 2017 Google Inc. - -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 - - https://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. -*/ - -// Package gnmi implements a gnmi server to mock a device with YANG models. -package gnmi - -import ( - "bytes" - "compress/gzip" - "encoding/json" - "fmt" - "io/ioutil" - "reflect" - "strconv" - "sync" - "time" - - "golang.org/x/net/context" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - - "github.com/golang/protobuf/proto" - "github.com/openconfig/gnmi/value" - "github.com/openconfig/ygot/util" - "github.com/openconfig/ygot/ygot" - "github.com/openconfig/ygot/ytypes" - log "github.com/sirupsen/logrus" - - dpb "github.com/golang/protobuf/protoc-gen-go/descriptor" - pb "github.com/openconfig/gnmi/proto/gnmi" -) - -// ConfigCallback is the signature of the function to apply a validated config to the physical device. -type ConfigCallback func(ygot.ValidatedGoStruct) error - -var ( - pbRootPath = &pb.Path{} - supportedEncodings = []pb.Encoding{pb.Encoding_PROTO, pb.Encoding_JSON_IETF, pb.Encoding_JSON} -) - -// Server struct maintains the data structure for device config and implements the interface of gnmi server. -// It supports Capabilities, Get, and Set APIs. -// Typical usage: -// g := grpc.NewServer() -// s, err := Server.NewServer(model, config, callback) -// pb.NewServer(g, s) -// reflection.Register(g) -// listen, err := net.Listen("tcp", ":8080") -// g.Serve(listen) -// -// For a real device, apply the config changes to the hardware in the callback function. -// Arguments: -// newConfig: new root config to be applied on the device. - -type Server struct { - model *Model - callback ConfigCallback - - config ygot.ValidatedGoStruct - mu sync.RWMutex // mu is the RW lock to protect the access to config -} - -// NewServer creates an instance of Server with given json config. -func NewServer(model *Model, config []byte, callback ConfigCallback) (*Server, error) { - rootStruct, err := model.NewConfigStruct(config) - if err != nil { - return nil, err - } - s := &Server{ - model: model, - config: rootStruct, - callback: callback, - } - if config != nil && s.callback != nil { - if err := s.callback(rootStruct); err != nil { - return nil, err - } - } - return s, nil -} - -// checkEncodingAndModel checks whether encoding and models are supported by the server. Return error if anything is unsupported. -func (s *Server) checkEncodingAndModel(encoding pb.Encoding, models []*pb.ModelData) error { - hasSupportedEncoding := false - for _, supportedEncoding := range supportedEncodings { - if encoding == supportedEncoding { - hasSupportedEncoding = true - break - } - } - if !hasSupportedEncoding { - return fmt.Errorf("unsupported encoding: %s", pb.Encoding_name[int32(encoding)]) - } - for _, m := range models { - isSupported := false - for _, supportedModel := range s.model.modelData { - if reflect.DeepEqual(m, supportedModel) { - isSupported = true - break - } - } - if !isSupported { - return fmt.Errorf("unsupported model: %v", m) - } - } - return nil -} - -// doDelete deletes the path from the json tree if the path exists. If success, -// it calls the callback function to apply the change to the device hardware. -func (s *Server) doDelete(jsonTree map[string]interface{}, prefix, path *pb.Path) (*pb.UpdateResult, error) { - // Update json tree of the device config - var curNode interface{} = jsonTree - pathDeleted := false - fullPath := gnmiFullPath(prefix, path) - schema := s.model.schemaTreeRoot - for i, elem := range fullPath.Elem { // Delete sub-tree or leaf node. - node, ok := curNode.(map[string]interface{}) - if !ok { - break - } - - // Delete node - if i == len(fullPath.Elem)-1 { - if elem.GetKey() == nil { - delete(node, elem.Name) - pathDeleted = true - break - } - pathDeleted = deleteKeyedListEntry(node, elem) - break - } - - if curNode, schema = getChildNode(node, schema, elem, false); curNode == nil { - break - } - } - if reflect.DeepEqual(fullPath, pbRootPath) { // Delete root - for k := range jsonTree { - delete(jsonTree, k) - } - } - - // Apply the validated operation to the config tree and device. - if pathDeleted { - newConfig, err := s.toGoStruct(jsonTree) - if err != nil { - return nil, status.Error(codes.Internal, err.Error()) - } - if s.callback != nil { - if applyErr := s.callback(newConfig); applyErr != nil { - if rollbackErr := s.callback(s.config); rollbackErr != nil { - return nil, status.Errorf(codes.Internal, "error in rollback the failed operation (%v): %v", applyErr, rollbackErr) - } - return nil, status.Errorf(codes.Aborted, "error in applying operation to device: %v", applyErr) - } - } - } - return &pb.UpdateResult{ - Path: path, - Op: pb.UpdateResult_DELETE, - }, nil -} - -// doReplaceOrUpdate validates the replace or update operation to be applied to -// the device, modifies the json tree of the config struct, then calls the -// callback function to apply the operation to the device hardware. -func (s *Server) doReplaceOrUpdate(jsonTree map[string]interface{}, op pb.UpdateResult_Operation, prefix, path *pb.Path, val *pb.TypedValue) (*pb.UpdateResult, error) { - // Validate the operation. - fullPath := gnmiFullPath(prefix, path) - emptyNode, _, err := ytypes.GetOrCreateNode(s.model.schemaTreeRoot, s.model.newRootValue(), fullPath) - if err != nil { - return nil, status.Errorf(codes.NotFound, "path %v is not found in the config structure: %v", fullPath, err) - } - var nodeVal interface{} - nodeStruct, ok := emptyNode.(ygot.ValidatedGoStruct) - if ok { - if err := s.model.jsonUnmarshaler(val.GetJsonIetfVal(), nodeStruct); err != nil { - return nil, status.Errorf(codes.InvalidArgument, "unmarshaling json data to config struct fails: %v", err) - } - if err := nodeStruct.Validate(); err != nil { - return nil, status.Errorf(codes.InvalidArgument, "config data validation fails: %v", err) - } - var err error - if nodeVal, err = ygot.ConstructIETFJSON(nodeStruct, &ygot.RFC7951JSONConfig{}); err != nil { - msg := fmt.Sprintf("error in constructing IETF JSON tree from config struct: %v", err) - log.Error(msg) - return nil, status.Error(codes.Internal, msg) - } - } else { - var err error - if nodeVal, err = value.ToScalar(val); err != nil { - return nil, status.Errorf(codes.Internal, "cannot convert leaf node to scalar type: %v", err) - } - } - - // Update json tree of the device config. - var curNode interface{} = jsonTree - schema := s.model.schemaTreeRoot - for i, elem := range fullPath.Elem { - switch node := curNode.(type) { - case map[string]interface{}: - // Set node value. - if i == len(fullPath.Elem)-1 { - if elem.GetKey() == nil { - if grpcStatusError := setPathWithoutAttribute(op, node, elem, nodeVal); grpcStatusError != nil { - return nil, grpcStatusError - } - break - } - if grpcStatusError := setPathWithAttribute(op, node, elem, nodeVal); grpcStatusError != nil { - return nil, grpcStatusError - } - break - } - - if curNode, schema = getChildNode(node, schema, elem, true); curNode == nil { - return nil, status.Errorf(codes.NotFound, "path elem not found: %v", elem) - } - case []interface{}: - return nil, status.Errorf(codes.NotFound, "incompatible path elem: %v", elem) - default: - return nil, status.Errorf(codes.Internal, "wrong node type: %T", curNode) - } - } - if reflect.DeepEqual(fullPath, pbRootPath) { // Replace/Update root. - if op == pb.UpdateResult_UPDATE { - return nil, status.Error(codes.Unimplemented, "update the root of config tree is unsupported") - } - nodeValAsTree, ok := nodeVal.(map[string]interface{}) - if !ok { - return nil, status.Errorf(codes.InvalidArgument, "expect a tree to replace the root, got a scalar value: %T", nodeVal) - } - for k := range jsonTree { - delete(jsonTree, k) - } - for k, v := range nodeValAsTree { - jsonTree[k] = v - } - } - newConfig, err := s.toGoStruct(jsonTree) - if err != nil { - return nil, status.Error(codes.Internal, err.Error()) - } - - // Apply the validated operation to the device. - if s.callback != nil { - if applyErr := s.callback(newConfig); applyErr != nil { - if rollbackErr := s.callback(s.config); rollbackErr != nil { - return nil, status.Errorf(codes.Internal, "error in rollback the failed operation (%v): %v", applyErr, rollbackErr) - } - return nil, status.Errorf(codes.Aborted, "error in applying operation to device: %v", applyErr) - } - } - return &pb.UpdateResult{ - Path: path, - Op: op, - }, nil -} - -func (s *Server) toGoStruct(jsonTree map[string]interface{}) (ygot.ValidatedGoStruct, error) { - jsonDump, err := json.Marshal(jsonTree) - if err != nil { - return nil, fmt.Errorf("error in marshaling IETF JSON tree to bytes: %v", err) - } - goStruct, err := s.model.NewConfigStruct(jsonDump) - if err != nil { - return nil, fmt.Errorf("error in creating config struct from IETF JSON data: %v", err) - } - return goStruct, nil -} - -// getGNMIServiceVersion returns a pointer to the gNMI service version string. -// The method is non-trivial because of the way it is defined in the proto file. -func getGNMIServiceVersion() (*string, error) { - gzB := (&pb.Update{}).ProtoReflect().Descriptor() - r, err := gzip.NewReader(bytes.NewReader([]byte(gzB.Name()))) - if err != nil { - return nil, fmt.Errorf("error in initializing gzip reader: %v", err) - } - defer r.Close() - b, err := ioutil.ReadAll(r) - if err != nil { - return nil, fmt.Errorf("error in reading gzip data: %v", err) - } - desc := &dpb.FileDescriptorProto{} - if err := proto.Unmarshal(b, desc); err != nil { - return nil, fmt.Errorf("error in unmarshaling proto: %v", err) - } - ver, err := proto.GetExtension(desc.Options, pb.E_GnmiService) - if err != nil { - return nil, fmt.Errorf("error in getting version from proto extension: %v", err) - } - return ver.(*string), nil -} - -// deleteKeyedListEntry deletes the keyed list entry from node that matches the -// path elem. If the entry is the only one in keyed list, deletes the entire -// list. If the entry is found and deleted, the function returns true. If it is -// not found, the function returns false. -func deleteKeyedListEntry(node map[string]interface{}, elem *pb.PathElem) bool { - curNode, ok := node[elem.Name] - if !ok { - return false - } - - keyedList, ok := curNode.([]interface{}) - if !ok { - return false - } - for i, n := range keyedList { - m, ok := n.(map[string]interface{}) - if !ok { - log.Errorf("expect map[string]interface{} for a keyed list entry, got %T", n) - return false - } - keyMatching := true - for k, v := range elem.Key { - attrVal, ok := m[k] - if !ok { - return false - } - if v != fmt.Sprintf("%v", attrVal) { - keyMatching = false - break - } - } - if keyMatching { - listLen := len(keyedList) - if listLen == 1 { - delete(node, elem.Name) - return true - } - keyedList[i] = keyedList[listLen-1] - node[elem.Name] = keyedList[0 : listLen-1] - return true - } - } - return false -} - -// gnmiFullPath builds the full path from the prefix and path. -func gnmiFullPath(prefix, path *pb.Path) *pb.Path { - fullPath := &pb.Path{Origin: path.Origin} - if path.GetElem() != nil { - fullPath.Elem = append(prefix.GetElem(), path.GetElem()...) - } - return fullPath -} - -// isNIl checks if an interface is nil or its value is nil. -func isNil(i interface{}) bool { - if i == nil { - return true - } - switch kind := reflect.ValueOf(i).Kind(); kind { - case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: - return reflect.ValueOf(i).IsNil() - default: - return false - } -} - -// setPathWithAttribute replaces or updates a child node of curNode in the IETF -// JSON config tree, where the child node is indexed by pathElem with attribute. -// The function returns grpc status error if unsuccessful. -func setPathWithAttribute(op pb.UpdateResult_Operation, curNode map[string]interface{}, pathElem *pb.PathElem, nodeVal interface{}) error { - nodeValAsTree, ok := nodeVal.(map[string]interface{}) - if !ok { - return status.Errorf(codes.InvalidArgument, "expect nodeVal is a json node of map[string]interface{}, received %T", nodeVal) - } - m := getKeyedListEntry(curNode, pathElem, true) - if m == nil { - return status.Errorf(codes.NotFound, "path elem not found: %v", pathElem) - } - if op == pb.UpdateResult_REPLACE { - for k := range m { - delete(m, k) - } - } - for attrKey, attrVal := range pathElem.GetKey() { - m[attrKey] = attrVal - if asNum, err := strconv.ParseFloat(attrVal, 64); err == nil { - m[attrKey] = asNum - } - for k, v := range nodeValAsTree { - if k == attrKey && fmt.Sprintf("%v", v) != attrVal { - return status.Errorf(codes.InvalidArgument, "invalid config data: %v is a path attribute", k) - } - } - } - for k, v := range nodeValAsTree { - m[k] = v - } - return nil -} - -// setPathWithoutAttribute replaces or updates a child node of curNode in the -// IETF config tree, where the child node is indexed by pathElem without -// attribute. The function returns grpc status error if unsuccessful. -func setPathWithoutAttribute(op pb.UpdateResult_Operation, curNode map[string]interface{}, pathElem *pb.PathElem, nodeVal interface{}) error { - target, hasElem := curNode[pathElem.Name] - nodeValAsTree, nodeValIsTree := nodeVal.(map[string]interface{}) - if op == pb.UpdateResult_REPLACE || !hasElem || !nodeValIsTree { - curNode[pathElem.Name] = nodeVal - return nil - } - targetAsTree, ok := target.(map[string]interface{}) - if !ok { - return status.Errorf(codes.Internal, "error in setting path: expect map[string]interface{} to update, got %T", target) - } - for k, v := range nodeValAsTree { - targetAsTree[k] = v - } - return nil -} - -// Capabilities returns supported encodings and supported models. -func (s *Server) Capabilities(ctx context.Context, req *pb.CapabilityRequest) (*pb.CapabilityResponse, error) { - ver, err := getGNMIServiceVersion() - if err != nil { - return nil, status.Errorf(codes.Internal, "error in getting gnmi service version: %v", err) - } - return &pb.CapabilityResponse{ - SupportedModels: s.model.modelData, - SupportedEncodings: supportedEncodings, - GNMIVersion: *ver, - }, nil -} - -// Get implements the Get RPC in gNMI spec. -func (s *Server) Get(ctx context.Context, req *pb.GetRequest) (*pb.GetResponse, error) { - if req.GetType() != pb.GetRequest_ALL { - return nil, status.Errorf(codes.Unimplemented, "unsupported request type: %s", pb.GetRequest_DataType_name[int32(req.GetType())]) - } - if err := s.checkEncodingAndModel(req.GetEncoding(), req.GetUseModels()); err != nil { - return nil, status.Error(codes.Unimplemented, err.Error()) - } - - prefix := req.GetPrefix() - paths := req.GetPath() - notifications := make([]*pb.Notification, 0) - - s.mu.RLock() - defer s.mu.RUnlock() - - for _, path := range paths { - // Get schema node for path from config struct. - fullPath := path - if prefix != nil { - fullPath = gnmiFullPath(prefix, path) - } - if fullPath.GetElem() == nil && fullPath.GetElement() != nil { - return nil, status.Error(codes.Unimplemented, "deprecated path element type is unsupported") - } - opts := []ytypes.GetNodeOpt{&ytypes.GetHandleWildcards{}, &ytypes.GetPartialKeyMatch{}} - nodes, err := ytypes.GetNode(s.model.schemaTreeRoot, s.config, fullPath, opts...) - if len(nodes) == 0 || err != nil || util.IsValueNil(nodes[0].Data) { - return nil, status.Errorf(codes.NotFound, "path %v not found: %v", fullPath, err) - } - for _, n := range nodes { - node := n.Data - ts := time.Now().UnixNano() - - nodeStruct, ok := node.(ygot.GoStruct) - // Return leaf node. - if !ok { - var val *pb.TypedValue - switch kind := reflect.ValueOf(node).Kind(); kind { - case reflect.Ptr, reflect.Interface: - var err error - val, err = value.FromScalar(reflect.ValueOf(node).Elem().Interface()) - if err != nil { - msg := fmt.Sprintf("leaf node %v does not contain a scalar type value: %v", path, err) - log.Error(msg) - return nil, status.Error(codes.Internal, msg) - } - case reflect.Int64: - enumMap, ok := s.model.enumData[reflect.TypeOf(node).Name()] - if !ok { - return nil, status.Error(codes.Internal, "not a GoStruct enumeration type") - } - val = &pb.TypedValue{ - Value: &pb.TypedValue_StringVal{ - StringVal: enumMap[reflect.ValueOf(node).Int()].Name, - }, - } - default: - return nil, status.Errorf(codes.Internal, "unexpected kind of leaf node type: %v %v", node, kind) - } - - update := &pb.Update{Path: path, Val: val} - notification := &pb.Notification{ - Timestamp: ts, - Prefix: prefix, - Update: []*pb.Update{update}, - } - notifications = append(notifications, notification) - continue - } - - if req.GetUseModels() != nil { - return nil, status.Errorf(codes.Unimplemented, "filtering Get using use_models is unsupported, got: %v", req.GetUseModels()) - } - - nots, err := ygot.TogNMINotifications(nodeStruct, ts, ygot.GNMINotificationsConfig{ - UsePathElem: false, - StringSlicePrefix: []string{"interfaces", "interface"}, - }) - - if err != nil { - return nil, err - } - - notifications = append(notifications, nots...) - - } - } - - return &pb.GetResponse{Notification: notifications}, nil -} - -// Set implements the Set RPC in gNMI spec. -func (s *Server) Set(ctx context.Context, req *pb.SetRequest) (*pb.SetResponse, error) { - s.mu.Lock() - defer s.mu.Unlock() - - jsonTree, err := ygot.ConstructIETFJSON(s.config, &ygot.RFC7951JSONConfig{}) - if err != nil { - msg := fmt.Sprintf("error in constructing IETF JSON tree from config struct: %v", err) - log.Error(msg) - return nil, status.Error(codes.Internal, msg) - } - - prefix := req.GetPrefix() - var results []*pb.UpdateResult - - for _, path := range req.GetDelete() { - res, grpcStatusError := s.doDelete(jsonTree, prefix, path) - if grpcStatusError != nil { - return nil, grpcStatusError - } - results = append(results, res) - } - for _, upd := range req.GetReplace() { - res, grpcStatusError := s.doReplaceOrUpdate(jsonTree, pb.UpdateResult_REPLACE, prefix, upd.GetPath(), upd.GetVal()) - if grpcStatusError != nil { - return nil, grpcStatusError - } - results = append(results, res) - } - for _, upd := range req.GetUpdate() { - res, grpcStatusError := s.doReplaceOrUpdate(jsonTree, pb.UpdateResult_UPDATE, prefix, upd.GetPath(), upd.GetVal()) - if grpcStatusError != nil { - return nil, grpcStatusError - } - results = append(results, res) - } - - jsonDump, err := json.Marshal(jsonTree) - if err != nil { - msg := fmt.Sprintf("error in marshaling IETF JSON tree to bytes: %v", err) - log.Error(msg) - return nil, status.Error(codes.Internal, msg) - } - rootStruct, err := s.model.NewConfigStruct(jsonDump) - if err != nil { - msg := fmt.Sprintf("error in creating config struct from IETF JSON data: %v", err) - log.Error(msg) - return nil, status.Error(codes.Internal, msg) - } - s.config = rootStruct - return &pb.SetResponse{ - Prefix: req.GetPrefix(), - Response: results, - }, nil -} - -// Subscribe method is not implemented. -func (s *Server) Subscribe(stream pb.GNMI_SubscribeServer) error { - return status.Error(codes.Unimplemented, "Subscribe is not implemented.") -} - -// InternalUpdate is an experimental feature to let the server update its -// internal states. Use it with your own risk. -func (s *Server) InternalUpdate(fp func(config ygot.ValidatedGoStruct) error) error { - s.mu.Lock() - defer s.mu.Unlock() - return fp(s.config) -} diff --git a/forks/google/gnmi/server_test.go b/forks/google/gnmi/server_test.go deleted file mode 100644 index 68ffea696df150f69e722256389f472a875de107..0000000000000000000000000000000000000000 --- a/forks/google/gnmi/server_test.go +++ /dev/null @@ -1,1161 +0,0 @@ -/* Copyright 2017 Google Inc. - -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 - - https://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. -*/ - -package gnmi - -import ( - "encoding/json" - "reflect" - "testing" - - "github.com/golang/protobuf/proto" - "github.com/openconfig/gnmi/value" - "github.com/openconfig/ygot/ygot" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - - pb "github.com/openconfig/gnmi/proto/gnmi" - - "github.com/google/gnxi/gnmi/modeldata" - "github.com/google/gnxi/gnmi/modeldata/gostruct" -) - -var ( - // model is the model for test config server. - model = &Model{ - modelData: modeldata.ModelData, - structRootType: reflect.TypeOf((*gostruct.Device)(nil)), - schemaTreeRoot: gostruct.SchemaTree["Device"], - jsonUnmarshaler: gostruct.Unmarshal, - enumData: gostruct.ΛEnum, - } -) - -func TestCapabilities(t *testing.T) { - s, err := NewServer(model, nil, nil) - if err != nil { - t.Fatalf("error in creating server: %v", err) - } - resp, err := s.Capabilities(nil, &pb.CapabilityRequest{}) - if err != nil { - t.Fatalf("got error %v, want nil", err) - } - if !reflect.DeepEqual(resp.GetSupportedModels(), model.modelData) { - t.Errorf("got supported models %v\nare not the same as\nmodel supported by the server %v", resp.GetSupportedModels(), model.modelData) - } - if !reflect.DeepEqual(resp.GetSupportedEncodings(), supportedEncodings) { - t.Errorf("got supported encodings %v\nare not the same as\nencodings supported by the server %v", resp.GetSupportedEncodings(), supportedEncodings) - } -} - -func TestGet(t *testing.T) { - jsonConfigRoot := `{ - "openconfig-system:system": { - "openconfig-openflow:openflow": { - "agent": { - "config": { - "failure-mode": "SECURE", - "max-backoff": 10 - } - } - } - }, - "openconfig-platform:components": { - "component": [ - { - "config": { - "name": "swpri1-1-1" - }, - "name": "swpri1-1-1" - } - ] - } - }` - - s, err := NewServer(model, []byte(jsonConfigRoot), nil) - if err != nil { - t.Fatalf("error in creating server: %v", err) - } - - tds := []struct { - desc string - textPbPath string - modelData []*pb.ModelData - wantRetCode codes.Code - wantRespVal interface{} - }{{ - desc: "get valid but non-existing node", - textPbPath: ` - elem: <name: "system" > - elem: <name: "clock" > - `, - wantRetCode: codes.NotFound, - }, { - desc: "root node", - wantRetCode: codes.OK, - wantRespVal: jsonConfigRoot, - }, { - desc: "get non-enum type", - textPbPath: ` - elem: <name: "system" > - elem: <name: "openflow" > - elem: <name: "agent" > - elem: <name: "config" > - elem: <name: "max-backoff" > - `, - wantRetCode: codes.OK, - wantRespVal: uint64(10), - }, { - desc: "get enum type", - textPbPath: ` - elem: <name: "system" > - elem: <name: "openflow" > - elem: <name: "agent" > - elem: <name: "config" > - elem: <name: "failure-mode" > - `, - wantRetCode: codes.OK, - wantRespVal: "SECURE", - }, { - desc: "root child node", - textPbPath: `elem: <name: "components" >`, - wantRetCode: codes.OK, - wantRespVal: `{ - "openconfig-platform:component": [{ - "config": { - "name": "swpri1-1-1" - }, - "name": "swpri1-1-1" - }]}`, - }, { - desc: "node with attribute", - textPbPath: ` - elem: <name: "components" > - elem: < - name: "component" - key: <key: "name" value: "swpri1-1-1" > - >`, - wantRetCode: codes.OK, - wantRespVal: `{ - "openconfig-platform:config": {"name": "swpri1-1-1"}, - "openconfig-platform:name": "swpri1-1-1" - }`, - }, { - desc: "node with attribute in its parent", - textPbPath: ` - elem: <name: "components" > - elem: < - name: "component" - key: <key: "name" value: "swpri1-1-1" > - > - elem: <name: "config" >`, - wantRetCode: codes.OK, - wantRespVal: `{"openconfig-platform:name": "swpri1-1-1"}`, - }, { - desc: "ref leaf node", - textPbPath: ` - elem: <name: "components" > - elem: < - name: "component" - key: <key: "name" value: "swpri1-1-1" > - > - elem: <name: "name" >`, - wantRetCode: codes.OK, - wantRespVal: "swpri1-1-1", - }, { - desc: "regular leaf node", - textPbPath: ` - elem: <name: "components" > - elem: < - name: "component" - key: <key: "name" value: "swpri1-1-1" > - > - elem: <name: "config" > - elem: <name: "name" >`, - wantRetCode: codes.OK, - wantRespVal: "swpri1-1-1", - }, { - desc: "non-existing node: wrong path name", - textPbPath: ` - elem: <name: "components" > - elem: < - name: "component" - key: <key: "foo" value: "swpri1-1-1" > - > - elem: <name: "bar" >`, - wantRetCode: codes.NotFound, - }, { - desc: "non-existing node: wrong path attribute", - textPbPath: ` - elem: <name: "components" > - elem: < - name: "component" - key: <key: "foo" value: "swpri2-2-2" > - > - elem: <name: "name" >`, - wantRetCode: codes.NotFound, - }, { - desc: "use of model data not supported", - modelData: []*pb.ModelData{{}}, - wantRetCode: codes.Unimplemented, - }} - - for _, td := range tds { - t.Run(td.desc, func(t *testing.T) { - runTestGet(t, s, td.textPbPath, td.wantRetCode, td.wantRespVal, td.modelData) - }) - } -} - -// runTestGet requests a path from the server by Get grpc call, and compares if -// the return code and response value are expected. -func runTestGet(t *testing.T, s *Server, textPbPath string, wantRetCode codes.Code, wantRespVal interface{}, useModels []*pb.ModelData) { - // Send request - var pbPath pb.Path - if err := proto.UnmarshalText(textPbPath, &pbPath); err != nil { - t.Fatalf("error in unmarshaling path: %v", err) - } - req := &pb.GetRequest{ - Path: []*pb.Path{&pbPath}, - Encoding: pb.Encoding_JSON_IETF, - UseModels: useModels, - } - resp, err := s.Get(nil, req) - - // Check return code - gotRetStatus, ok := status.FromError(err) - if !ok { - t.Fatal("got a non-grpc error from grpc call") - } - if gotRetStatus.Code() != wantRetCode { - t.Fatalf("got return code %v, want %v", gotRetStatus.Code(), wantRetCode) - } - - // Check response value - var gotVal interface{} - if resp != nil { - notifs := resp.GetNotification() - if len(notifs) != 1 { - t.Fatalf("got %d notifications, want 1", len(notifs)) - } - updates := notifs[0].GetUpdate() - if len(updates) != 1 { - t.Fatalf("got %d updates in the notification, want 1", len(updates)) - } - val := updates[0].GetVal() - if val.GetJsonIetfVal() == nil { - gotVal, err = value.ToScalar(val) - if err != nil { - t.Errorf("got: %v, want a scalar value", gotVal) - } - } else { - // Unmarshal json data to gotVal container for comparison - if err := json.Unmarshal(val.GetJsonIetfVal(), &gotVal); err != nil { - t.Fatalf("error in unmarshaling IETF JSON data to json container: %v", err) - } - var wantJSONStruct interface{} - if err := json.Unmarshal([]byte(wantRespVal.(string)), &wantJSONStruct); err != nil { - t.Fatalf("error in unmarshaling IETF JSON data to json container: %v", err) - } - wantRespVal = wantJSONStruct - } - } - - if !reflect.DeepEqual(gotVal, wantRespVal) { - t.Errorf("got: %v (%T),\nwant %v (%T)", gotVal, gotVal, wantRespVal, wantRespVal) - } -} - -type gnmiSetTestCase struct { - desc string // description of test case. - initConfig string // config before the operation. - op pb.UpdateResult_Operation // operation type. - textPbPath string // text format of gnmi Path proto. - val *pb.TypedValue // value for UPDATE/REPLACE operations. always nil for DELETE. - wantRetCode codes.Code // grpc return code. - wantConfig string // config after the operation. -} - -func TestDelete(t *testing.T) { - tests := []gnmiSetTestCase{{ - desc: "delete leaf node", - initConfig: `{ - "system": { - "config": { - "hostname": "switch_a", - "login-banner": "Hello!" - } - } - }`, - op: pb.UpdateResult_DELETE, - textPbPath: ` - elem: <name: "system" > - elem: <name: "config" > - elem: <name: "login-banner" > - `, - wantRetCode: codes.OK, - wantConfig: `{ - "system": { - "config": { - "hostname": "switch_a" - } - } - }`, - }, { - desc: "delete sub-tree", - initConfig: `{ - "system": { - "clock": { - "config": { - "timezone-name": "Europe/Stockholm" - } - }, - "config": { - "hostname": "switch_a" - } - } - }`, - op: pb.UpdateResult_DELETE, - textPbPath: ` - elem: <name: "system" > - elem: <name: "clock" > - `, - wantRetCode: codes.OK, - wantConfig: `{ - "system": { - "config": { - "hostname": "switch_a" - } - } - }`, - }, { - desc: "delete a sub-tree with only one leaf node", - initConfig: `{ - "system": { - "clock": { - "config": { - "timezone-name": "Europe/Stockholm" - } - }, - "config": { - "hostname": "switch_a" - } - } - }`, - op: pb.UpdateResult_DELETE, - textPbPath: ` - elem: <name: "system" > - elem: <name: "clock" > - elem: <name: "config" > - `, - wantRetCode: codes.OK, - wantConfig: `{ - "system": { - "config": { - "hostname": "switch_a" - } - } - }`, - }, { - desc: "delete a leaf node whose parent has only this child", - initConfig: `{ - "system": { - "clock": { - "config": { - "timezone-name": "Europe/Stockholm" - } - }, - "config": { - "hostname": "switch_a" - } - } - }`, - op: pb.UpdateResult_DELETE, - textPbPath: ` - elem: <name: "system" > - elem: <name: "clock" > - elem: <name: "config" > - elem: <name: "timezone-name" > - `, - wantRetCode: codes.OK, - wantConfig: `{ - "system": { - "config": { - "hostname": "switch_a" - } - } - }`, - }, { - desc: "delete root", - initConfig: `{ - "system": { - "config": { - "hostname": "switch_a" - } - } - }`, - op: pb.UpdateResult_DELETE, - wantRetCode: codes.OK, - wantConfig: `{}`, - }, { - desc: "delete non-existing node", - initConfig: `{ - "system": { - "clock": { - "config": { - "timezone-name": "Europe/Stockholm" - } - } - } - }`, - op: pb.UpdateResult_DELETE, - textPbPath: ` - elem: <name: "system" > - elem: <name: "clock" > - elem: <name: "config" > - elem: <name: "foo-bar" > - `, - wantRetCode: codes.OK, - wantConfig: `{ - "system": { - "clock": { - "config": { - "timezone-name": "Europe/Stockholm" - } - } - } - }`, - }, { - desc: "delete node with non-existing precedent path", - initConfig: `{ - "system": { - "clock": { - "config": { - "timezone-name": "Europe/Stockholm" - } - } - } - }`, - op: pb.UpdateResult_DELETE, - textPbPath: ` - elem: <name: "system" > - elem: <name: "clock" > - elem: <name: "foo-bar" > - elem: <name: "timezone-name" > - `, - wantRetCode: codes.OK, - wantConfig: `{ - "system": { - "clock": { - "config": { - "timezone-name": "Europe/Stockholm" - } - } - } - }`, - }, { - desc: "delete node with non-existing attribute in precedent path", - initConfig: `{ - "system": { - "clock": { - "config": { - "timezone-name": "Europe/Stockholm" - } - } - } - }`, - op: pb.UpdateResult_DELETE, - textPbPath: ` - elem: <name: "system" > - elem: <name: "clock" > - elem: < - name: "config" - key: <key: "name" value: "foo" > - > - elem: <name: "timezone-name" >`, - wantRetCode: codes.OK, - wantConfig: `{ - "system": { - "clock": { - "config": { - "timezone-name": "Europe/Stockholm" - } - } - } - }`, - }, { - desc: "delete node with non-existing attribute", - initConfig: `{ - "system": { - "clock": { - "config": { - "timezone-name": "Europe/Stockholm" - } - } - } - }`, - op: pb.UpdateResult_DELETE, - textPbPath: ` - elem: <name: "system" > - elem: <name: "clock" > - elem: <name: "config" > - elem: < - name: "timezone-name" - key: <key: "name" value: "foo" > - > - elem: <name: "timezone-name" >`, - wantRetCode: codes.OK, - wantConfig: `{ - "system": { - "clock": { - "config": { - "timezone-name": "Europe/Stockholm" - } - } - } - }`, - }, { - desc: "delete leaf node with attribute in its precedent path", - initConfig: `{ - "components": { - "component": [ - { - "name": "swpri1-1-1", - "config": { - "name": "swpri1-1-1" - }, - "state": { - "name": "swpri1-1-1", - "mfg-name": "foo bar inc." - } - } - ] - } - }`, - op: pb.UpdateResult_DELETE, - textPbPath: ` - elem: <name: "components" > - elem: < - name: "component" - key: <key: "name" value: "swpri1-1-1" > - > - elem: <name: "state" > - elem: <name: "mfg-name" >`, - wantRetCode: codes.OK, - wantConfig: `{ - "components": { - "component": [ - { - "name": "swpri1-1-1", - "config": { - "name": "swpri1-1-1" - }, - "state": { - "name": "swpri1-1-1" - } - } - ] - } - }`, - }, { - desc: "delete sub-tree with attribute in its precedent path", - initConfig: `{ - "components": { - "component": [ - { - "name": "swpri1-1-1", - "config": { - "name": "swpri1-1-1" - }, - "state": { - "name": "swpri1-1-1", - "mfg-name": "foo bar inc." - } - } - ] - } - }`, - op: pb.UpdateResult_DELETE, - textPbPath: ` - elem: <name: "components" > - elem: < - name: "component" - key: <key: "name" value: "swpri1-1-1" > - > - elem: <name: "state" >`, - wantRetCode: codes.OK, - wantConfig: `{ - "components": { - "component": [ - { - "name": "swpri1-1-1", - "config": { - "name": "swpri1-1-1" - } - } - ] - } - }`, - }, { - desc: "delete path node with attribute", - initConfig: `{ - "components": { - "component": [ - { - "name": "swpri1-1-1", - "config": { - "name": "swpri1-1-1" - } - }, - { - "name": "swpri1-1-2", - "config": { - "name": "swpri1-1-2" - } - } - ] - } - }`, - op: pb.UpdateResult_DELETE, - textPbPath: ` - elem: <name: "components" > - elem: < - name: "component" - key: <key: "name" value: "swpri1-1-1" > - >`, - wantRetCode: codes.OK, - wantConfig: `{ - "components": { - "component": [ - { - "name": "swpri1-1-2", - "config": { - "name": "swpri1-1-2" - } - } - ] - } - }`, - }, { - desc: "delete path node with int type attribute", - initConfig: `{ - "system": { - "openflow": { - "controllers": { - "controller": [ - { - "config": { - "name": "main" - }, - "connections": { - "connection": [ - { - "aux-id": 0, - "config": { - "address": "192.0.2.10", - "aux-id": 0 - } - } - ] - }, - "name": "main" - } - ] - } - } - } - }`, - op: pb.UpdateResult_DELETE, - textPbPath: ` - elem: <name: "system" > - elem: <name: "openflow" > - elem: <name: "controllers" > - elem: < - name: "controller" - key: <key: "name" value: "main" > - > - elem: <name: "connections" > - elem: < - name: "connection" - key: <key: "aux-id" value: "0" > - > - `, - wantRetCode: codes.OK, - wantConfig: `{ - "system": { - "openflow": { - "controllers": { - "controller": [ - { - "config": { - "name": "main" - }, - "name": "main" - } - ] - } - } - } - }`, - }, { - desc: "delete leaf node with non-existing attribute value", - initConfig: `{ - "components": { - "component": [ - { - "name": "swpri1-1-1", - "config": { - "name": "swpri1-1-1" - } - } - ] - } - }`, - op: pb.UpdateResult_DELETE, - textPbPath: ` - elem: <name: "components" > - elem: < - name: "component" - key: <key: "name" value: "foo" > - >`, - wantRetCode: codes.OK, - wantConfig: `{ - "components": { - "component": [ - { - "name": "swpri1-1-1", - "config": { - "name": "swpri1-1-1" - } - } - ] - } - }`, - }, { - desc: "delete leaf node with non-existing attribute value in precedent path", - initConfig: `{ - "components": { - "component": [ - { - "name": "swpri1-1-1", - "config": { - "name": "swpri1-1-1" - }, - "state": { - "name": "swpri1-1-1", - "mfg-name": "foo bar inc." - } - } - ] - } - }`, - op: pb.UpdateResult_DELETE, - textPbPath: ` - elem: <name: "components" > - elem: < - name: "component" - key: <key: "name" value: "foo" > - > - elem: <name: "state" > - elem: <name: "mfg-name" > - `, - wantRetCode: codes.OK, - wantConfig: `{ - "components": { - "component": [ - { - "name": "swpri1-1-1", - "config": { - "name": "swpri1-1-1" - }, - "state": { - "name": "swpri1-1-1", - "mfg-name": "foo bar inc." - } - } - ] - } - }`, - }} - - for _, tc := range tests { - t.Run(tc.desc, func(t *testing.T) { - runTestSet(t, model, tc) - }) - } -} - -func TestReplace(t *testing.T) { - systemConfig := `{ - "system": { - "clock": { - "config": { - "timezone-name": "Europe/Stockholm" - } - }, - "config": { - "hostname": "switch_a", - "login-banner": "Hello!" - } - } - }` - - tests := []gnmiSetTestCase{{ - desc: "replace root", - initConfig: `{}`, - op: pb.UpdateResult_REPLACE, - val: &pb.TypedValue{ - Value: &pb.TypedValue_JsonIetfVal{ - JsonIetfVal: []byte(systemConfig), - }}, - wantRetCode: codes.OK, - wantConfig: systemConfig, - }, { - desc: "replace a subtree", - initConfig: `{}`, - op: pb.UpdateResult_REPLACE, - textPbPath: ` - elem: <name: "system" > - elem: <name: "clock" > - `, - val: &pb.TypedValue{ - Value: &pb.TypedValue_JsonIetfVal{ - JsonIetfVal: []byte(`{"config": {"timezone-name": "US/New York"}}`), - }, - }, - wantRetCode: codes.OK, - wantConfig: `{ - "system": { - "clock": { - "config": { - "timezone-name": "US/New York" - } - } - } - }`, - }, { - desc: "replace a keyed list subtree", - initConfig: `{}`, - op: pb.UpdateResult_REPLACE, - textPbPath: ` - elem: <name: "components" > - elem: < - name: "component" - key: <key: "name" value: "swpri1-1-1" > - >`, - val: &pb.TypedValue{ - Value: &pb.TypedValue_JsonIetfVal{ - JsonIetfVal: []byte(`{"config": {"name": "swpri1-1-1"}}`), - }, - }, - wantRetCode: codes.OK, - wantConfig: `{ - "components": { - "component": [ - { - "name": "swpri1-1-1", - "config": { - "name": "swpri1-1-1" - } - } - ] - } - }`, - }, { - desc: "replace node with int type attribute in its precedent path", - initConfig: `{ - "system": { - "openflow": { - "controllers": { - "controller": [ - { - "config": { - "name": "main" - }, - "name": "main" - } - ] - } - } - } - }`, - op: pb.UpdateResult_REPLACE, - textPbPath: ` - elem: <name: "system" > - elem: <name: "openflow" > - elem: <name: "controllers" > - elem: < - name: "controller" - key: <key: "name" value: "main" > - > - elem: <name: "connections" > - elem: < - name: "connection" - key: <key: "aux-id" value: "0" > - > - elem: <name: "config" > - `, - val: &pb.TypedValue{ - Value: &pb.TypedValue_JsonIetfVal{ - JsonIetfVal: []byte(`{"address": "192.0.2.10", "aux-id": 0}`), - }, - }, - wantRetCode: codes.OK, - wantConfig: `{ - "system": { - "openflow": { - "controllers": { - "controller": [ - { - "config": { - "name": "main" - }, - "connections": { - "connection": [ - { - "aux-id": 0, - "config": { - "address": "192.0.2.10", - "aux-id": 0 - } - } - ] - }, - "name": "main" - } - ] - } - } - } - }`, - }, { - desc: "replace a leaf node of int type", - initConfig: `{}`, - op: pb.UpdateResult_REPLACE, - textPbPath: ` - elem: <name: "system" > - elem: <name: "openflow" > - elem: <name: "agent" > - elem: <name: "config" > - elem: <name: "backoff-interval" > - `, - val: &pb.TypedValue{ - Value: &pb.TypedValue_IntVal{IntVal: 5}, - }, - wantRetCode: codes.OK, - wantConfig: `{ - "system": { - "openflow": { - "agent": { - "config": { - "backoff-interval": 5 - } - } - } - } - }`, - }, { - desc: "replace a leaf node of string type", - initConfig: `{}`, - op: pb.UpdateResult_REPLACE, - textPbPath: ` - elem: <name: "system" > - elem: <name: "openflow" > - elem: <name: "agent" > - elem: <name: "config" > - elem: <name: "datapath-id" > - `, - val: &pb.TypedValue{ - Value: &pb.TypedValue_StringVal{StringVal: "00:16:3e:00:00:00:00:00"}, - }, - wantRetCode: codes.OK, - wantConfig: `{ - "system": { - "openflow": { - "agent": { - "config": { - "datapath-id": "00:16:3e:00:00:00:00:00" - } - } - } - } - }`, - }, { - desc: "replace a leaf node of enum type", - initConfig: `{}`, - op: pb.UpdateResult_REPLACE, - textPbPath: ` - elem: <name: "system" > - elem: <name: "openflow" > - elem: <name: "agent" > - elem: <name: "config" > - elem: <name: "failure-mode" > - `, - val: &pb.TypedValue{ - Value: &pb.TypedValue_StringVal{StringVal: "SECURE"}, - }, - wantRetCode: codes.OK, - wantConfig: `{ - "system": { - "openflow": { - "agent": { - "config": { - "failure-mode": "SECURE" - } - } - } - } - }`, - }, { - desc: "replace an non-existing leaf node", - initConfig: `{}`, - op: pb.UpdateResult_REPLACE, - textPbPath: ` - elem: <name: "system" > - elem: <name: "openflow" > - elem: <name: "agent" > - elem: <name: "config" > - elem: <name: "foo-bar" > - `, - val: &pb.TypedValue{ - Value: &pb.TypedValue_StringVal{StringVal: "SECURE"}, - }, - wantRetCode: codes.NotFound, - wantConfig: `{}`, - }} - - for _, tc := range tests { - t.Run(tc.desc, func(t *testing.T) { - runTestSet(t, model, tc) - }) - } -} - -func TestUpdate(t *testing.T) { - tests := []gnmiSetTestCase{{ - desc: "update leaf node", - initConfig: `{ - "system": { - "config": { - "hostname": "switch_a" - } - } - }`, - op: pb.UpdateResult_UPDATE, - textPbPath: ` - elem: <name: "system" > - elem: <name: "config" > - elem: <name: "domain-name" > - `, - val: &pb.TypedValue{ - Value: &pb.TypedValue_StringVal{StringVal: "foo.bar.com"}, - }, - wantRetCode: codes.OK, - wantConfig: `{ - "system": { - "config": { - "domain-name": "foo.bar.com", - "hostname": "switch_a" - } - } - }`, - }, { - desc: "update subtree", - initConfig: `{ - "system": { - "config": { - "hostname": "switch_a" - } - } - }`, - op: pb.UpdateResult_UPDATE, - textPbPath: ` - elem: <name: "system" > - elem: <name: "config" > - `, - val: &pb.TypedValue{ - Value: &pb.TypedValue_JsonIetfVal{ - JsonIetfVal: []byte(`{"domain-name": "foo.bar.com", "hostname": "switch_a"}`), - }, - }, - wantRetCode: codes.OK, - wantConfig: `{ - "system": { - "config": { - "domain-name": "foo.bar.com", - "hostname": "switch_a" - } - } - }`, - }} - - for _, tc := range tests { - t.Run(tc.desc, func(t *testing.T) { - runTestSet(t, model, tc) - }) - } -} - -func runTestSet(t *testing.T, m *Model, tc gnmiSetTestCase) { - // Create a new server with empty config - s, err := NewServer(m, []byte(tc.initConfig), nil) - if err != nil { - t.Fatalf("error in creating config server: %v", err) - } - - // Send request - var pbPath pb.Path - if err := proto.UnmarshalText(tc.textPbPath, &pbPath); err != nil { - t.Fatalf("error in unmarshaling path: %v", err) - } - var req *pb.SetRequest - switch tc.op { - case pb.UpdateResult_DELETE: - req = &pb.SetRequest{Delete: []*pb.Path{&pbPath}} - case pb.UpdateResult_REPLACE: - req = &pb.SetRequest{Replace: []*pb.Update{{Path: &pbPath, Val: tc.val}}} - case pb.UpdateResult_UPDATE: - req = &pb.SetRequest{Update: []*pb.Update{{Path: &pbPath, Val: tc.val}}} - default: - t.Fatalf("invalid op type: %v", tc.op) - } - _, err = s.Set(nil, req) - - // Check return code - gotRetStatus, ok := status.FromError(err) - if !ok { - t.Fatal("got a non-grpc error from grpc call") - } - if gotRetStatus.Code() != tc.wantRetCode { - t.Fatalf("got return code %v, want %v\nerror message: %v", gotRetStatus.Code(), tc.wantRetCode, err) - } - - // Check server config - wantConfigStruct, err := m.NewConfigStruct([]byte(tc.wantConfig)) - if err != nil { - t.Fatalf("wantConfig data cannot be loaded as a config struct: %v", err) - } - wantConfigJSON, err := ygot.ConstructIETFJSON(wantConfigStruct, &ygot.RFC7951JSONConfig{}) - if err != nil { - t.Fatalf("error in constructing IETF JSON tree from wanted config: %v", err) - } - gotConfigJSON, err := ygot.ConstructIETFJSON(s.config, &ygot.RFC7951JSONConfig{}) - if err != nil { - t.Fatalf("error in constructing IETF JSON tree from server config: %v", err) - } - if !reflect.DeepEqual(gotConfigJSON, wantConfigJSON) { - t.Fatalf("got server config %v\nwant: %v", gotConfigJSON, wantConfigJSON) - } -} diff --git a/forks/google/gnmi/util.go b/forks/google/gnmi/util.go deleted file mode 100644 index 73d17b49f7cab79a20236681c773b50844060af4..0000000000000000000000000000000000000000 --- a/forks/google/gnmi/util.go +++ /dev/null @@ -1,102 +0,0 @@ -package gnmi - -import ( - "fmt" - "strconv" - - "github.com/openconfig/goyang/pkg/yang" - log "github.com/sirupsen/logrus" - - pb "github.com/openconfig/gnmi/proto/gnmi" -) - -// getChildNode gets a node's child with corresponding schema specified by path -// element. If not found and createIfNotExist is set as true, an empty node is -// created and returned. -func getChildNode(node map[string]interface{}, schema *yang.Entry, elem *pb.PathElem, createIfNotExist bool) (interface{}, *yang.Entry) { - var nextSchema *yang.Entry - var ok bool - - if nextSchema, ok = schema.Dir[elem.Name]; !ok { - return nil, nil - } - - var nextNode interface{} - if elem.GetKey() == nil { - if nextNode, ok = node[elem.Name]; !ok { - if createIfNotExist { - node[elem.Name] = make(map[string]interface{}) - nextNode = node[elem.Name] - } - } - return nextNode, nextSchema - } - - nextNode = getKeyedListEntry(node, elem, createIfNotExist) - return nextNode, nextSchema -} - -// getKeyedListEntry finds the keyed list entry in node by the name and key of -// path elem. If entry is not found and createIfNotExist is true, an empty entry -// will be created (the list will be created if necessary). -func getKeyedListEntry(node map[string]interface{}, elem *pb.PathElem, createIfNotExist bool) map[string]interface{} { - curNode, ok := node[elem.Name] - if !ok { - if !createIfNotExist { - return nil - } - - // Create a keyed list as node child and initialize an entry. - m := make(map[string]interface{}) - for k, v := range elem.Key { - m[k] = v - if vAsNum, err := strconv.ParseFloat(v, 64); err == nil { - m[k] = vAsNum - } - } - node[elem.Name] = []interface{}{m} - return m - } - - // Search entry in keyed list. - keyedList, ok := curNode.([]interface{}) - if !ok { - return nil - } - for _, n := range keyedList { - m, ok := n.(map[string]interface{}) - if !ok { - log.Errorf("wrong keyed list entry type: %T", n) - return nil - } - keyMatching := true - // must be exactly match - for k, v := range elem.Key { - attrVal, ok := m[k] - if !ok { - return nil - } - if v != fmt.Sprintf("%v", attrVal) { - keyMatching = false - break - } - } - if keyMatching { - return m - } - } - if !createIfNotExist { - return nil - } - - // Create an entry in keyed list. - m := make(map[string]interface{}) - for k, v := range elem.Key { - m[k] = v - if vAsNum, err := strconv.ParseFloat(v, 64); err == nil { - m[k] = vAsNum - } - } - node[elem.Name] = append(keyedList, m) - return m -} diff --git a/go.mod b/go.mod index 9822234c73e01a5119746554b44198af1da233b9..094fad6678d5b4f509352d45e740fb669f42bba8 100644 --- a/go.mod +++ b/go.mod @@ -1,25 +1,57 @@ -module code.fbi.h-da.de/cocsn/gosdn +module code.fbi.h-da.de/danet/gosdn -go 1.14 +go 1.17 require ( - code.fbi.h-da.de/cocsn/yang-models v0.0.4 - github.com/aristanetworks/goarista v0.0.0-20201120222254-94a892eb0c6a - github.com/golang/protobuf v1.5.0 - github.com/google/gnxi v0.0.0-20201221102247-c26672548161 - github.com/google/uuid v1.1.2 - github.com/neo4j/neo4j-go-driver v1.8.3 - github.com/openconfig/gnmi v0.0.0-20200617225440-d2b4e6a45802 - github.com/openconfig/goyang v0.2.3 - github.com/openconfig/ygot v0.10.0 - github.com/sirupsen/logrus v1.7.0 - github.com/spf13/cobra v1.1.1 - github.com/spf13/viper v1.7.1 - github.com/stretchr/testify v1.6.1 - golang.org/x/net v0.0.0-20201216054612-986b41b23924 - google.golang.org/grpc v1.34.0 - google.golang.org/protobuf v1.26.0 - k8s.io/api v0.20.5 - k8s.io/apimachinery v0.20.5 - k8s.io/client-go v0.20.5 + code.fbi.h-da.de/danet/api v0.2.5-0.20210722102157-e7e463162450 + code.fbi.h-da.de/danet/forks/goarista v0.0.0-20210709163519-47ee8958ef40 + code.fbi.h-da.de/danet/forks/google v0.0.0-20210709163519-47ee8958ef40 + code.fbi.h-da.de/danet/yang-models v0.1.0 + github.com/docker/docker v20.10.11+incompatible + github.com/google/go-cmp v0.5.6 + github.com/google/uuid v1.2.0 + github.com/openconfig/gnmi v0.0.0-20210914185457-51254b657b7d + github.com/openconfig/goyang v0.3.1 + github.com/openconfig/ygot v0.12.5 + github.com/prometheus/client_golang v1.9.0 + github.com/sirupsen/logrus v1.8.1 + github.com/spf13/cobra v1.1.3 + github.com/spf13/viper v1.9.0 + github.com/stretchr/objx v0.2.0 // indirect + github.com/stretchr/testify v1.7.0 + google.golang.org/grpc v1.40.0 + google.golang.org/protobuf v1.27.1 +) + +require ( + github.com/beorn7/perks v1.0.1 // indirect + github.com/cespare/xxhash/v2 v2.1.1 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/fsnotify/fsnotify v1.5.1 // indirect + github.com/golang/glog v1.0.0 // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/hashicorp/hcl v1.0.0 // indirect + github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/kylelemons/godebug v1.1.0 // indirect + github.com/magiconair/properties v1.8.5 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect + github.com/mitchellh/mapstructure v1.4.2 // indirect + github.com/pelletier/go-toml v1.9.4 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/prometheus/client_model v0.2.0 // indirect + github.com/prometheus/common v0.18.0 // indirect + github.com/prometheus/procfs v0.6.0 // indirect + github.com/spf13/afero v1.6.0 // indirect + github.com/spf13/cast v1.4.1 // indirect + github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/subosito/gotenv v1.2.0 // indirect + golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9 // indirect + golang.org/x/sys v0.0.0-20211123173158-ef496fb156ab // indirect + golang.org/x/text v0.3.7 // indirect + golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect + google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1 // indirect + gopkg.in/ini.v1 v1.64.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect ) diff --git a/go.sum b/go.sum index df1bca3a02416ecdb2b8129aa30f24d7ceea3832..427cfd8f8a6f4ec2f16ff2a17b223137b7ebfbdb 100644 --- a/go.sum +++ b/go.sum @@ -9,75 +9,124 @@ cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6T 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 v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= +cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= +cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= +cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= +cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= 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/firestore v1.6.0/go.mod h1:afJwI0vaXwAG54kI7A//lP/lSPDkQORQuMkv56TxEPU= 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.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.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/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.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= -code.fbi.h-da.de/cocsn/yang-models v0.0.4 h1:y/Ph5CaD2NJDPjoOuS59iKrMYf9bvpg2/hefC2RG6E4= -code.fbi.h-da.de/cocsn/yang-models v0.0.4/go.mod h1:7MnNmAQ9o84BpUepcaV6RB1mBGCNyXVJcdbKUl6rK0g= +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= +code.fbi.h-da.de/danet/api v0.2.5-0.20210722102157-e7e463162450 h1:gImcnMybH6KceaLQzbD2FDjV0kRL88WobBDQVH92d9o= +code.fbi.h-da.de/danet/api v0.2.5-0.20210722102157-e7e463162450/go.mod h1:kjazkgCFLje+z4BBNBLlyozhQUnkJd0sqlZz1Axe0wM= +code.fbi.h-da.de/danet/forks/goarista v0.0.0-20210709163519-47ee8958ef40 h1:x7rVYGqfJSMWuYBp+JE6JVMcFP03Gx0mnR2ftsgqjVI= +code.fbi.h-da.de/danet/forks/goarista v0.0.0-20210709163519-47ee8958ef40/go.mod h1:uVe3gCeF2DcIho8K9CIO46uAkHW/lUF+fAaUX1vHrF0= +code.fbi.h-da.de/danet/forks/google v0.0.0-20210709163519-47ee8958ef40 h1:B45k5tGEdjjdsKK4f+0dQoyReFmsWdwYEzHofA7DPM8= +code.fbi.h-da.de/danet/forks/google v0.0.0-20210709163519-47ee8958ef40/go.mod h1:Uutdj5aA3jpzfNm3C8gt2wctYE6cRrdyZsILUgJ+tMY= +code.fbi.h-da.de/danet/yang-models v0.1.0 h1:C658HkGYZSV5Eq5nY2NnC/PQPKp3BaTXwGZICCr0sqk= +code.fbi.h-da.de/danet/yang-models v0.1.0/go.mod h1:0TNkzPA1OW9lF9ey18GQWcMd4ORvOfhhFOA/t0SjenM= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= -github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg= -github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= -github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= -github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= -github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= -github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= -github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Microsoft/go-winio v0.4.15/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= -github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/Shopify/sarama v1.26.1/go.mod h1:NbSGBSSndYaIhRcBtY9V0U7AyH+x71bG668AuWys/yU= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/sarama v1.28.0/go.mod h1:j/2xTrU39dlzBmsxF1eQ2/DdWrxyBCl6pzz7a81o/ZY= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= +github.com/YangModels/yang v0.0.0-20210623190019-3af23949e11a/go.mod h1:0x0kZfKdo2j6P7LQNX2V7/LJWVbHaK3lEHwUj01nL70= +github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= 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/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/aristanetworks/fsnotify v1.4.2/go.mod h1:D/rtu7LpjYM8tRJphJ0hUBYpjai8SfX+aSNsWDTq/Ks= github.com/aristanetworks/glog v0.0.0-20191112221043-67e8567f59f3/go.mod h1:KASm+qXFKs/xjSoWn30NrWBBvdTTQq+UjkhjEJHfSFA= -github.com/aristanetworks/goarista v0.0.0-20201120222254-94a892eb0c6a h1:R7ghEBfKIqu/SDpGHS9Nj1fWPxkvxh6Lv4Wq6eS95G4= -github.com/aristanetworks/goarista v0.0.0-20201120222254-94a892eb0c6a/go.mod h1:Q4lsGfepQE823ePrSNr2CjCz1oeeMECJ6k1yBVujrZg= +github.com/aristanetworks/goarista v0.0.0-20210706081233-a582b785a9ce h1:oKfxZ+MdgljqTE33vdUuIUUXQp3VFH9yqqgxCRyB48w= +github.com/aristanetworks/goarista v0.0.0-20210706081233-a582b785a9ce/go.mod h1:drswc1gdKErwWsW+gV2R5ELcuHehg5pZD2tat4B65Ik= github.com/aristanetworks/splunk-hec-go v0.3.3/go.mod h1:1VHO9r17b0K7WmOlLb9nTk/2YanvOEnLMUgsFrxBROc= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= 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/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= +github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= +github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= 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.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= +github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= +github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff/v4 v4.0.0/go.mod h1:eEew/i+1Q6OrCDZh3WiXYv3+nJwBASZ8Bog/87DQnVg= +github.com/cenkalti/backoff/v4 v4.1.0/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= 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 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= 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/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= 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/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.13+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-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= 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-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 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= @@ -86,58 +135,62 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v1.13.1/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v20.10.11+incompatible h1:OqzI/g/W54LczvhnccGqniFoQghHx3pklbLuhfXpqGo= +github.com/docker/docker v20.10.11+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= -github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/dsnet/compress v0.0.1/go.mod h1:Aw8dCMJ7RioblQeTqt88akK31OvO8Dhf5JflhBbQEHo= github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY= +github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= -github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= 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.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= +github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= -github.com/frankban/quicktest v1.7.2/go.mod h1:jaStnuzAqU1AJdCO0l53JDCJrVDKcS03DbaAcR7Ks/o= +github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= +github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= +github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= 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/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI= +github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= -github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= 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-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/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= 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-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= -github.com/go-logr/logr v0.2.0 h1:QvGt2nLcHH0WK9orKa+ppBPAxREcH364nPUedEpK0TY= -github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= -github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= -github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= -github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= -github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= -github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/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.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= -github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v0.0.0-20210429001901-424d2337a529/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= +github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 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= @@ -148,11 +201,15 @@ github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFU 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/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= 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= @@ -161,64 +218,97 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq 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 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4= 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/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 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/gnxi v0.0.0-20201221102247-c26672548161 h1:8Huhvr/sx+mAUzfujNPTCbq+z4LG1qUIu0smjXTaBw0= -github.com/google/gnxi v0.0.0-20201221102247-c26672548161/go.mod h1:dPTuHPVOqxZ2yGKPjymiMt1vrZa8KHXWKX+Lx1z5d88= +github.com/google/gnxi v0.0.0-20210423111716-4b504ef806a7 h1:cJ62uhbZcclaYm9gq4JNyazqSY7bUEggwZdw0nHTT7o= +github.com/google/gnxi v0.0.0-20210423111716-4b504ef806a7/go.mod h1:dPTuHPVOqxZ2yGKPjymiMt1vrZa8KHXWKX+Lx1z5d88= 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.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +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 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= -github.com/google/gofuzz v1.1.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/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= 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/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/protobuf v3.11.4+incompatible/go.mod h1:lUQ9D1ePzbH2PrIS7ob/bjm9HXyH5WHB0Akwh7URreM= +github.com/google/protobuf v3.14.0+incompatible/go.mod h1:lUQ9D1ePzbH2PrIS7ob/bjm9HXyH5WHB0Akwh7URreM= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= +github.com/google/uuid v1.0.0/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.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs= +github.com/google/uuid v1.2.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/googleapis/gnostic v0.4.1 h1:DLJCy1n/vrD4HPjOvYcT8aYQXpPIzoRZONaYwyycI+I= -github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= +github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00 h1:l5lAOZEym3oK3SQ2HBHWsJUfbNBiTXJDeW2QDxw9AQ0= github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= +github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= +github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -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-middleware v1.0.1-0.20190118093823-f849b5445de4/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.9.5/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/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= +github.com/hashicorp/consul/api v1.10.1/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= 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-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= 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-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= 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-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= 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= @@ -226,63 +316,90 @@ 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/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/imdario/mergo v0.3.5 h1:JboBksRwiiAJWvIYJVo46AfV+IAIKZpfrSzVKj42R4Q= -github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/influxdata/influxdb1-client v0.0.0-20200827194710-b269163b24ab/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= +github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= +github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= +github.com/jcmturner/gokrb5/v8 v8.4.2/go.mod h1:sb+Xq/fTY5yktf/VxLsE3wlfPqQjp0aWNYyvBVK62bc= +github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +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.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.8/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/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 h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= 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/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +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.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.9.8/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.10.1/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.10.10/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.11.9/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= -github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/cpuid/v2 v2.0.2/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/pgzip v1.2.4/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= -github.com/klauspost/reedsolomon v1.9.3/go.mod h1:CwCi+NUr9pqSVktrkN+Ondf06rkhYZ/pcNv7fu+8Un4= +github.com/klauspost/reedsolomon v1.9.11/go.mod h1:nLvuzNvy1ZDNQW30IuMc2ZWCbiqrJgdLoUS2X8HAUVg= 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/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 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= 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/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= +github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= +github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.4 h1:8KGKTcQQGm0Kv7vEbKFErAoAOFyyacLStRtQSeYtvkY= github.com/magiconair/properties v1.8.4/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/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls= +github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= +github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mholt/archiver/v3 v3.5.0/go.mod h1:qqTTPUK/HZPFgFQ/TJ3BzvTpF/dPtFVJXdQbCmeMxwc= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= 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= @@ -290,123 +407,177 @@ github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS4 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.3 h1:SzB1nHZ2Xi+17FP0zVQBHIZqvwRN9408fJO8h+eeNA8= github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.2 h1:6h7AQ0yhTcIsmFmnAwQls75jp2Gzs4iB8W7pjMO+rqo= +github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/moby/moby v1.13.1/go.mod h1:fDXVQ6+S340veQPv35CzDahGBmHsiclFwfEygB/TWMc= 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 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= -github.com/neo4j/neo4j-go-driver v1.8.3 h1:yfuo9YBAlezdIiogu92GwEir/81RD81dNwS5mY/wAIk= -github.com/neo4j/neo4j-go-driver v1.8.3/go.mod h1:ncO5VaFWh0Nrt+4KT4mOZboaczBZcLuHrG+/sUeP8gI= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= +github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0= +github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.0 h1:Iw5WCbBcaAAd0fpRb1c9r5YCylv4XDoCSigm1zLevwU= -github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= -github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.9.0 h1:R1uwffexN6Pr340GtYRIdZmAiN4J+iw6WG4wog1DUXg= -github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= -github.com/openconfig/gnmi v0.0.0-20190823184014-89b2bf29312c/go.mod h1:t+O9It+LKzfOAhKTT5O0ehDix+MTqbtT0T9t+7zzOvc= +github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/openconfig/gnmi v0.0.0-20200414194230-1597cc0f2600/go.mod h1:M/EcuapNQgvzxo1DDXHK4tx3QpYM/uG4l591v33jG2A= github.com/openconfig/gnmi v0.0.0-20200508230933-d19cebf5e7be/go.mod h1:M/EcuapNQgvzxo1DDXHK4tx3QpYM/uG4l591v33jG2A= -github.com/openconfig/gnmi v0.0.0-20200617225440-d2b4e6a45802 h1:WXFwJlWOJINlwlyAZuNo4GdYZS6qPX36+rRUncLmN8Q= github.com/openconfig/gnmi v0.0.0-20200617225440-d2b4e6a45802/go.mod h1:M/EcuapNQgvzxo1DDXHK4tx3QpYM/uG4l591v33jG2A= +github.com/openconfig/gnmi v0.0.0-20210226144353-8eae1937bf84/go.mod h1:H/20NXlnWbCPFC593nxpiKJ+OU//7mW7s7Qk7uVdg3Q= +github.com/openconfig/gnmi v0.0.0-20210527163611-d3a3e30199da/go.mod h1:H/20NXlnWbCPFC593nxpiKJ+OU//7mW7s7Qk7uVdg3Q= +github.com/openconfig/gnmi v0.0.0-20210707145734-c69a5df04b53/go.mod h1:h365Ifq35G6kLZDQlRvrccTt2LKK90VpjZLMNGxJRYc= +github.com/openconfig/gnmi v0.0.0-20210914185457-51254b657b7d h1:ENKx1I2+/8C70C69qGDw8zfHXFsPnSMtZyf9F2GjN/k= +github.com/openconfig/gnmi v0.0.0-20210914185457-51254b657b7d/go.mod h1:h365Ifq35G6kLZDQlRvrccTt2LKK90VpjZLMNGxJRYc= github.com/openconfig/goyang v0.0.0-20200115183954-d0a48929f0ea/go.mod h1:dhXaV0JgHJzdrHi2l+w0fZrwArtXL7jEFoiqLEdmkvU= github.com/openconfig/goyang v0.2.2/go.mod h1:vX61x01Q46AzbZUzG617vWqh/cB+aisc+RrNkXRd3W8= -github.com/openconfig/goyang v0.2.3 h1:pYxQ+VG6KNS3N5zkQeLmIBtc3gRs6JHZOKMD2/knlv4= github.com/openconfig/goyang v0.2.3/go.mod h1:vX61x01Q46AzbZUzG617vWqh/cB+aisc+RrNkXRd3W8= -github.com/openconfig/reference v0.0.0-20190727015836-8dfd928c9696/go.mod h1:ym2A+zigScwkSEb/cVQB0/ZMpU3rqiH6X7WRRsxgOGw= +github.com/openconfig/goyang v0.2.5/go.mod h1:vX61x01Q46AzbZUzG617vWqh/cB+aisc+RrNkXRd3W8= +github.com/openconfig/goyang v0.2.7/go.mod h1:vX61x01Q46AzbZUzG617vWqh/cB+aisc+RrNkXRd3W8= +github.com/openconfig/goyang v0.2.9/go.mod h1:vX61x01Q46AzbZUzG617vWqh/cB+aisc+RrNkXRd3W8= +github.com/openconfig/goyang v0.3.1 h1:27E8ibpoCh/c6TvptzkEl2l207xSlEfRPk2jaFw83VI= +github.com/openconfig/goyang v0.3.1/go.mod h1:vX61x01Q46AzbZUzG617vWqh/cB+aisc+RrNkXRd3W8= +github.com/openconfig/gribi v0.1.1-0.20210423184541-ce37eb4ba92f/go.mod h1:OoH46A2kV42cIXGyviYmAlGmn6cHjGduyC2+I9d/iVs= +github.com/openconfig/grpctunnel v0.0.0-20210610163803-fde4a9dc048d/go.mod h1:x9tAZ4EwqCQ0jI8D6S8Yhw9Z0ee7/BxWQX0k0Uib5Q8= +github.com/openconfig/public v0.0.0-20210617063307-ed650bd969af/go.mod h1:yUxbtuG3OQ8eTwMtkvFhpd1eMZUXxLKxBqVth5Qn09U= +github.com/openconfig/reference v0.0.0-20201210185750-72ca4cfd4abd/go.mod h1:ym2A+zigScwkSEb/cVQB0/ZMpU3rqiH6X7WRRsxgOGw= github.com/openconfig/ygot v0.6.0/go.mod h1:o30svNf7O0xK+R35tlx95odkDmZWS9JyWWQSmIhqwAs= github.com/openconfig/ygot v0.9.0/go.mod h1:oCQNdXnv7dWc8scTDgoFkauv1wwplJn5HspHcjlxSAQ= -github.com/openconfig/ygot v0.10.0 h1:EmgwLXbFiCBmEUlSI4/1fPuRzgf4EsD0sThmAmRqbYM= -github.com/openconfig/ygot v0.10.0/go.mod h1:oCQNdXnv7dWc8scTDgoFkauv1wwplJn5HspHcjlxSAQ= +github.com/openconfig/ygot v0.10.4/go.mod h1:oCQNdXnv7dWc8scTDgoFkauv1wwplJn5HspHcjlxSAQ= +github.com/openconfig/ygot v0.11.2/go.mod h1:5q5fz1SDPGUwMyzbm8Ns2Krul+32euNSU89ZmrGrSK8= +github.com/openconfig/ygot v0.12.5 h1:J63zt59nnehyPPkI3/QG/eSnslyHFhwuuh0Gyl4uXBs= +github.com/openconfig/ygot v0.12.5/go.mod h1:kJN0yCXIH07dOXvNBEFm3XxXdnDD5NI6K99tnD5x49c= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= +github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= +github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/getopt v0.0.0-20190409184431-ee0cd42419d3/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o= +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.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM= github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= -github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= -github.com/pierrec/lz4 v2.4.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM= +github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= +github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pierrec/lz4 v2.6.0+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4/v4 v4.0.3/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pierrec/lz4/v4 v4.1.1/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= 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/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= 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/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= 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.4.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= +github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.9.0 h1:Rrch9mh17XcxvEu9D9DEpb4isxjGBtcevQjKvxPRQIU= +github.com/prometheus/client_golang v1.9.0/go.mod h1:FqZLKOZnGdFAhOK4nqGHa7D66IdsO+O441Eve7ptJDU= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/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.1.0/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.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= 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.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= +github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= +github.com/prometheus/common v0.18.0 h1:WCVKW7aL6LEe1uryfI9dnEc2ZqNB1Fn0ok930v0iL1Y= +github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/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.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= -github.com/prometheus/procfs v0.0.10/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4= +github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= 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/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/sagikazarmark/crypt v0.1.0/go.mod h1:B/mN0msZuINBtQ1zZLEQcegFJJf9vnYIR88KRMEuODE= +github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= 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.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM= -github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs= github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= -github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= 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/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= 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.4.1 h1:asw9sl74539yqavKaglDM5hFpdJVK0Y5Dr/JOgQ89nQ= github.com/spf13/afero v1.4.1/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= +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 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v1.1.1 h1:KfztREH0tPxJJ+geloSLaAkaPkr4ki2Er5quFV1TDo4= +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 v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= +github.com/spf13/cobra v1.1.3 h1:xghbfqPkxzxP3C/f3n5DdpAbdKLj4ZE4BWQI362l53M= +github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= 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 v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= 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.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk= github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/spf13/viper v1.9.0 h1:yR6EXjTp0y0cLN8OZg1CRZmOBdI88UcGkhgyJhu6nZk= +github.com/spf13/viper v1.9.0/go.mod h1:+i6ajR7OX2XaiBkrcZJFK21htRk7eDeLg7+O6bhUPP4= +github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= 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.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= @@ -415,46 +586,75 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf 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 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/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/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161/go.mod h1:wM7WEvslTq+iOEAMDLSzhVuOt5BRZ05WirO+b09GHQU= github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b/go.mod h1:5XA7W9S6mni3h5uvOC75dA3m9CCCaS83lltmc0ukdi4= -github.com/tjfoc/gmsm v1.3.0/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w= +github.com/tjfoc/gmsm v1.4.0/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE= +github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= github.com/ulikunitz/xz v0.5.7/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xtaci/kcp-go v5.4.20+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE= github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae/go.mod h1:gXtu8J62kEgmN++bm9BVICuT/e8yiLI2KFobd/TRFsE= +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= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= +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.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= 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/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +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.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +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-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-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191219195013-becbf705a915/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0 h1:hb9wdF1z5waM+dSIICn1l0DkLVDT3hqhhQsDNUmHPRE= -golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 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= @@ -477,6 +677,8 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl 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= @@ -484,6 +686,10 @@ 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/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-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -492,6 +698,7 @@ golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73r 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-20190125091013-d26f9f9a57f3/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= @@ -500,8 +707,10 @@ golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn 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-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478/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= @@ -509,22 +718,54 @@ golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLL 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-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +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-20201216054612-986b41b23924 h1:QsnDpLLOKwHBBDa8nDws4DYNc/ryVW2vCpxCs09d4PY= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201216054612-986b41b23924/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-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9 h1:0qxwC5n+ttVOINCBeRHO0nq9X7uy8SDsPoi5OaCdIEI= +golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 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 h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= 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-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/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/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= @@ -532,53 +773,93 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h 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-20181122145206-62eef0e2fa9b/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-20190222072716-a9d3bda3a223/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-20190616124812-15dcb6c0061f/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-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/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-20200219091948-cb0a6d8edb6c/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-20200519105757-fe76b779f299/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-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e h1:AyodaIpKjppX+cBfTASF2E1US3H2JFBj920Ot3rtDjs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/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-20210303074136-134d130e1a04/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-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644/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-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211123173158-ef496fb156ab h1:rfJ1bsoJQQIAoAxTxB7bme+vHrNkRw8CqfsYh9w54cw= +golang.org/x/sys v0.0.0-20211123173158-ef496fb156ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 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 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc= 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-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 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-20200630173020-3af7569d3a1e h1:EHBhcS0mlXEAVwNyO2dLfjToGsyY4j24pTs2ScHnX7s= -golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/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-20180828015842-6cd1fcedba52/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-20181030221726-6c7e314b6563/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= @@ -589,12 +870,14 @@ golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBn 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-20190614205625-5aca471b1d59/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-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-20190907020128-2ca718005c18/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-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/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= @@ -603,20 +886,44 @@ golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtn 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-20200103221440-774c71fcf114/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-20200221224223-e1da425f72fd/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.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= 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 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= 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= @@ -626,18 +933,38 @@ google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsb 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.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= +google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= +google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= +google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= +google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 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 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM= 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/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-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= 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= @@ -650,22 +977,78 @@ google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvx 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-20200519141106-08726f379972/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-20201214200347-8c77b98c765d h1:HV9Z9qMhQEsdlvxNFELgQ11RkMzO3CMkjEySjCtuLes= +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-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-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/genproto v0.0.0-20210708141623-e76da96a951f/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= +google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1 h1:b9mVrqYfq3P4bCdaLg1qtBnPzUYgglsIdjZkL/fQVOE= +google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= 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.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.1/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.34.0 h1:raiipEjMOIC/TO2AvyTxP25XFdLxNIBwzDh3FM3XztI= +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.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.40.0 h1:AGJ0Ih4mHjSeibYkFGh1dD9KJ/eOtZ93I6hoHhukQ5Q= +google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.0.1/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= 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= @@ -677,67 +1060,54 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD 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 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/bsm/ratelimit.v1 v1.0.0-20160220154919-db14e161995a/go.mod h1:KF9sEfUPAXdG8Oev9e99iLGnl2uJMjc5B+4y3O7x610= 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-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U= gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/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/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= -gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/ini.v1 v1.51.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/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo= -gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q= -gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4= -gopkg.in/jcmturner/gokrb5.v7 v7.5.0/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM= -gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8= +gopkg.in/ini.v1 v1.63.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.64.0 h1:Mj2zXEXcNb5joEiSA0zc3HZpTst/iyjNiR4CN8tDzOg= +gopkg.in/ini.v1 v1.64.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/redis.v4 v4.2.4/go.mod h1:8KREHdypkCEojGKQcjMqAODMICIVwZAONWq8RowTITA= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= 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 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= 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 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 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= -k8s.io/api v0.20.5 h1:zsMTffV0Le2EiI0aKvlTHEnXGxk1HiqGRhJcCPiI7JI= -k8s.io/api v0.20.5/go.mod h1:FQjAceXnVaWDeov2YUWhOb6Yt+5UjErkp6UO3nczO1Y= -k8s.io/apimachinery v0.20.5 h1:wO/FxMVRn223rAKxnBbwCyuN96bS9MFTIvP0e/V7cps= -k8s.io/apimachinery v0.20.5/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= -k8s.io/client-go v0.20.5 h1:dJGtYUvFrFGjQ+GjXEIby0gZWdlAOc0xJBJqY3VyDxA= -k8s.io/client-go v0.20.5/go.mod h1:Ee5OOMMYvlH8FCZhDsacjMlCBwetbGZETwo1OA+e6Zw= -k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= -k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= -k8s.io/klog/v2 v2.4.0 h1:7+X0fUguPyrKEC4WjH8iGDg3laWgMo5tMnRTIGTTxGQ= -k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= -k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= -k8s.io/utils v0.0.0-20201110183641-67b214c5f920 h1:CbnUZsM497iRC5QMVkHwyl8s2tB3g7yaSHkYPkpgelw= -k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= 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/structured-merge-diff/v4 v4.0.2 h1:YHQV7Dajm86OuqnIR6zAelnDWBRjo+YhYV9PmGrh1s8= -sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= -sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= +sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/gosdn.png b/gosdn.png deleted file mode 100644 index b16c83696fe11f6b983da0bf923457ecf59add8d..0000000000000000000000000000000000000000 Binary files a/gosdn.png and /dev/null differ diff --git a/gosdn.puml b/gosdn.puml deleted file mode 100644 index 1dc2379006cdef8990adf2f73dc4fe5ddd414c51..0000000000000000000000000000000000000000 --- a/gosdn.puml +++ /dev/null @@ -1,118 +0,0 @@ -@startuml -namespace nucleus { - class ClientConfig << (S,Aquamarine) >> { - + Identifier string - + Endpoint string - + Username string - + Password string - + GjsonDefaultPath string - + GjsonConnectionsPath string - - } - class Core << (S,Aquamarine) >> { - - devices <font color=blue>map</font>[string]Device - - southboundInterfaces <font color=blue>map</font>[string]interfaces.SouthboundInterface - - prinipalNetworkDomains <font color=blue>map</font>[uuid.UUID]interfaces.PrincipalNetworkDomain - - database database.Database - - config controllerConfig - - + IsRunning <font color=blue>chan</font> bool - - - readControllerConfig(configFileController string) error - - + Init(socket string, configFileController string, configFileClient string, IsRunningChannel <font color=blue>chan</font> bool) - + AttachDatabase() - + Shutdown() - - } - class Device << (S,Aquamarine) >> { - - device ygot.GoStruct - - + SBI interfaces.SouthboundInterface - + Config DeviceConfig - - } - class DeviceConfig << (S,Aquamarine) >> { - + Identifier uuid.UUID - + Endpoint string - + Username string - + Password string - - } - interface PrincipalNetworkDomain { - + Destroy() error - + AddSbi() error - + RemoveSbi() error - + AddDevice( interfaces.Device) error - + RemoveDevice(uuid uuid.UUID) error - - } - interface SouthboundInterface { - } - class buf << (S,Aquamarine) >> { - + Write(p []byte) (int, error) - - } - class controllerConfig << (S,Aquamarine) >> { - + CliSocket string - + DatabaseSocket string - + DatabaseUser string - + DatabasePassword string - + DatabaseCrypto bool - + ConfigPath string - - } - class logConnection << (S,Aquamarine) >> { - - stream proto.GrpcCli_CreateLogStreamServer - - id string - - active bool - - error <font color=blue>chan</font> error - - } - class nucleus.buf << (T, #FF7700) >> { - } - class pndImplementation << (S,Aquamarine) >> { - - name string - - sbiContainer <font color=blue>map</font>[string]*interfaces.SouthboundInterface - - devices <font color=blue>map</font>[uuid.UUID]Device - - + Destroy() error - + AddSbi() error - + RemoveSbi() error - + AddDevice(device Device) error - + RemoveDevice(uuid uuid.UUID) error - - } - class server << (S,Aquamarine) >> { - - core *Core - - logConnections []*logConnection - - + SayHello(ctx context.Context, in *proto.HelloRequest) (*proto.HelloReply, error) - + CreateLogStream(req *emptypb.Empty, stream proto.GrpcCli_CreateLogStreamServer) error - + BroadcastLog(log *proto.LogReply) - + Shutdown(ctx context.Context, in *proto.ShutdownRequest) (*proto.ShutdownReply, error) - + TAPIGetEdge(ctx context.Context, in *proto.TAPIRequest) (*proto.TAPIReply, error) - + TAPIGetEdgeNode(ctx context.Context, in *proto.TAPIRequest) (*proto.TAPIReply, error) - + TAPIGetLink(ctx context.Context, in *proto.TAPIRequest) (*proto.TAPIReply, error) - - } -} -"proto.UnimplementedGrpcCliServer" *-- "nucleus.server" - - -namespace sbi { - class OpenConfig << (S,Aquamarine) >> { - - name string - - clientContainer []Client - - + AddClient() error - + RemoveClient() error - + CollectHeartbeats() error - + ListClients() <font color=blue>map</font>[int]interfaces.Client - - } -} - - -"__builtin__.[]byte" #.. "nucleus.buf" -@enduml diff --git a/http.go b/http.go new file mode 100644 index 0000000000000000000000000000000000000000..3a6fea20116994fd8834346d26189e3c47156f2d --- /dev/null +++ b/http.go @@ -0,0 +1,45 @@ +package gosdn + +import ( + "context" + "fmt" + "net/http" + "time" + + "github.com/prometheus/client_golang/prometheus/promhttp" + log "github.com/sirupsen/logrus" +) + +func stopHttpServer() error { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + log.Info("shutting down http server") + return c.httpServer.Shutdown(ctx) +} + +func registerHttpHandler() { + defer func() { + if r := recover(); r != nil { + fmt.Println("Recovered in f", r) + } + }() + http.HandleFunc("/livez", healthCheck) + http.HandleFunc("/readyz", readynessCheck) + http.Handle("/metrics", promhttp.Handler()) +} + +func startHttpServer() { + registerHttpHandler() + c.httpServer = &http.Server{Addr: ":8080"} + go func() { + log.Info(c.httpServer.ListenAndServe()) + }() +} + +func healthCheck(writer http.ResponseWriter, request *http.Request) { + writer.WriteHeader(http.StatusOK) +} + +func readynessCheck(writer http.ResponseWriter, request *http.Request) { + writer.WriteHeader(http.StatusOK) +} diff --git a/http_test.go b/http_test.go new file mode 100644 index 0000000000000000000000000000000000000000..786c75dca55a9e0b25f1ffe51978ca370ebd91d4 --- /dev/null +++ b/http_test.go @@ -0,0 +1,49 @@ +package gosdn + +import ( + "net/http" + "testing" +) + +func Test_httpApi(t *testing.T) { + tests := []struct { + name string + request string + want *http.Response + wantErr bool + }{ + { + name: "/livez", + request: apiEndpoint + "/livez", + want: &http.Response{StatusCode: http.StatusOK}, + wantErr: false, + }, + { + name: "/readyz", + request: apiEndpoint + "/readyz", + want: &http.Response{StatusCode: http.StatusOK}, + wantErr: false, + }, + { + name: "/metrics", + request: apiEndpoint + "/metrics", + want: &http.Response{StatusCode: http.StatusOK}, + wantErr: false, + }, + } + coreLock.Lock() + startHttpServer() + coreLock.Unlock() + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := http.Get(tt.request) + if (err != nil) != tt.wantErr { + t.Errorf("httpApi() error = %v, wantErr %v", err, tt.wantErr) + return + } + if got.StatusCode != tt.want.StatusCode { + t.Errorf("httpApi() got: %v, want %v", got.StatusCode, tt.want.StatusCode) + } + }) + } +} diff --git a/initialise_test.go b/initialise_test.go new file mode 100644 index 0000000000000000000000000000000000000000..bba39814b70fd1cbf9807c86baa0c024457ba733 --- /dev/null +++ b/initialise_test.go @@ -0,0 +1,42 @@ +package gosdn + +import ( + "os" + "testing" + + "code.fbi.h-da.de/danet/gosdn/config" + + "github.com/google/uuid" + log "github.com/sirupsen/logrus" +) + +const apiEndpoint = "http://localhost:8080" + +// UUIDs for test cases +var mdid uuid.UUID +var defaultPndID uuid.UUID +var cuid uuid.UUID + +func TestMain(m *testing.M) { + log.SetReportCaller(true) + log.SetLevel(config.LogLevel) + + readTestUUIDs() + os.Exit(m.Run()) +} + +func readTestUUIDs() { + var err error + mdid, err = uuid.Parse("688a264e-5f85-40f8-bd13-afc42fcd5c7a") + if err != nil { + log.Fatal(err) + } + defaultPndID, err = uuid.Parse("b4016412-eec5-45a1-aa29-f59915357bad") + if err != nil { + log.Fatal(err) + } + cuid, err = uuid.Parse("3e8219b0-e926-400d-8660-217f2a25a7c6") + if err != nil { + log.Fatal(err) + } +} diff --git a/interfaces/change/change.go b/interfaces/change/change.go new file mode 100644 index 0000000000000000000000000000000000000000..460a1af047a5eb56534fc3cffcc901aaddbe44ec --- /dev/null +++ b/interfaces/change/change.go @@ -0,0 +1,28 @@ +package change + +import ( + "time" + + ppb "code.fbi.h-da.de/danet/api/go/gosdn/pnd" + "github.com/google/uuid" + "github.com/openconfig/ygot/ygot" +) + +// Change is an intended change to an OND. It is unique and immutable. +// It has a cuid, a timestamp, and holds both the previous and the new +// state. It keeps track if the state is committed and confirmed. A callback +// exists to acess the proper transport for the changed OND +type Change interface { + ID() uuid.UUID + Commit() error + Confirm() error + State() ppb.Change_State + Age() time.Duration +} + +// Payload contains two ygot.GoStructs, the first represents the original state +// before the change was applied and the second repesents the modified state. +type Payload struct { + Original ygot.GoStruct + Modified ygot.GoStruct +} diff --git a/interfaces/device/device.go b/interfaces/device/device.go new file mode 100644 index 0000000000000000000000000000000000000000..1775d27b0117bfb8e7918ed47363168586b55aed --- /dev/null +++ b/interfaces/device/device.go @@ -0,0 +1,20 @@ +package device + +import ( + "code.fbi.h-da.de/danet/gosdn/interfaces/southbound" + "code.fbi.h-da.de/danet/gosdn/interfaces/transport" + "github.com/google/uuid" + "github.com/openconfig/ygot/ygot" + "google.golang.org/protobuf/proto" +) + +// Device represents an Orchestrated Network Device (OND) which is managed by +// nucleus +type Device interface { + ID() uuid.UUID + Model() ygot.GoStruct + Transport() transport.Transport + Name() string + SBI() southbound.SouthboundInterface + ProcessResponse(proto.Message) error +} diff --git a/interfaces/networkdomain/pnd.go b/interfaces/networkdomain/pnd.go new file mode 100644 index 0000000000000000000000000000000000000000..9b83d85ecb029f7cf7da3c9740a12877c1fe6a43 --- /dev/null +++ b/interfaces/networkdomain/pnd.go @@ -0,0 +1,39 @@ +package networkdomain + +import ( + ppb "code.fbi.h-da.de/danet/api/go/gosdn/pnd" + tpb "code.fbi.h-da.de/danet/api/go/gosdn/transport" + "code.fbi.h-da.de/danet/gosdn/interfaces/change" + "code.fbi.h-da.de/danet/gosdn/interfaces/device" + "code.fbi.h-da.de/danet/gosdn/interfaces/southbound" + "code.fbi.h-da.de/danet/gosdn/interfaces/store" + "github.com/google/uuid" + "google.golang.org/protobuf/proto" +) + +// NetworkDomain provides an interface for network domain implementations +// like principal network domain or logical network domain. +type NetworkDomain interface { + Destroy() error + AddSbi(s southbound.SouthboundInterface) error + RemoveSbi(uuid.UUID) error + AddDevice(name string, opts *tpb.TransportOption, sid uuid.UUID) error + AddDeviceFromStore(name string, deviceUUID uuid.UUID, opt *tpb.TransportOption, sid uuid.UUID) error + GetDevice(identifier string) (device.Device, error) + RemoveDevice(uuid.UUID) error + Devices() []uuid.UUID + ChangeOND(uuid uuid.UUID, operation ppb.ApiOperation, path string, value ...string) (uuid.UUID, error) + Request(uuid.UUID, string) (proto.Message, error) + RequestAll(string) error + GetName() string + GetDescription() string + MarshalDevice(string) (string, error) + ContainsDevice(uuid.UUID) bool + GetSBIs() store.Store + ID() uuid.UUID + PendingChanges() []uuid.UUID + CommittedChanges() []uuid.UUID + GetChange(uuid.UUID) (change.Change, error) + Commit(uuid.UUID) error + Confirm(uuid.UUID) error +} diff --git a/interfaces/southbound/sbi.go b/interfaces/southbound/sbi.go new file mode 100644 index 0000000000000000000000000000000000000000..0024081c35a14b367adab9e077ad716ba3f8db03 --- /dev/null +++ b/interfaces/southbound/sbi.go @@ -0,0 +1,27 @@ +package southbound + +import ( + spb "code.fbi.h-da.de/danet/api/go/gosdn/southbound" + "github.com/openconfig/ygot/ygot" + + "github.com/google/uuid" + gpb "github.com/openconfig/gnmi/proto/gnmi" + "github.com/openconfig/goyang/pkg/yang" + "github.com/openconfig/ygot/ytypes" +) + +// SouthboundInterface provides an +// interface for SBI implementations +type SouthboundInterface interface { // nolint + // deprecated + SbiIdentifier() string + + // SetNode injects SBI specific model + // representation to the transport. + // Needed for type assertion. + SetNode(schema *yang.Entry, root interface{}, path *gpb.Path, val interface{}, opts ...ytypes.SetNodeOpt) error + Schema() *ytypes.Schema + ID() uuid.UUID + Type() spb.Type + Unmarshal([]byte, *gpb.Path, ygot.ValidatedGoStruct, ...ytypes.UnmarshalOpt) error +} diff --git a/interfaces/store/store.go b/interfaces/store/store.go new file mode 100644 index 0000000000000000000000000000000000000000..7d4d4a6a7f51c1cbeb3f60b55587fd9fc205f858 --- /dev/null +++ b/interfaces/store/store.go @@ -0,0 +1,17 @@ +package store + +import "github.com/google/uuid" + +// Storable provides an interface for the controller's storage architecture. +type Storable interface { + ID() uuid.UUID +} + +// Store describes an interface for store implementations. +type Store interface { + Exists(id uuid.UUID) bool + Add(item Storable) error + Get(id uuid.UUID) (Storable, error) + Delete(id uuid.UUID) error + UUIDs() []uuid.UUID +} diff --git a/interfaces/transport/transport.go b/interfaces/transport/transport.go new file mode 100644 index 0000000000000000000000000000000000000000..24f33f65a51306fd6301a75075a25494c224d572 --- /dev/null +++ b/interfaces/transport/transport.go @@ -0,0 +1,19 @@ +package transport + +import ( + "context" + + "code.fbi.h-da.de/danet/gosdn/interfaces/change" + + "github.com/openconfig/ygot/ytypes" +) + +// Transport provides an interface for Transport implementations +// like RESTCONF or gnmi +type Transport interface { + Get(ctx context.Context, params ...string) (interface{}, error) + Set(ctx context.Context, payload change.Payload) error + Subscribe(ctx context.Context, params ...string) error + Type() string + ProcessResponse(resp interface{}, root interface{}, models *ytypes.Schema) error +} diff --git a/metrics/prometheus.go b/metrics/prometheus.go new file mode 100644 index 0000000000000000000000000000000000000000..d07cc48b5fe3b4dad65c5fa75fd9a90f8ae102e9 --- /dev/null +++ b/metrics/prometheus.go @@ -0,0 +1,34 @@ +package metrics + +import ( + "time" + + "github.com/prometheus/client_golang/prometheus" +) + +// nolint +// TODO: add description +func StartHook(labels prometheus.Labels, counter *prometheus.CounterVec) time.Time { + counter.With(labels).Inc() + return time.Now() +} + +// nolint +// TODO: add description +func FinishHook(labels prometheus.Labels, start time.Time, counter *prometheus.CounterVec, hist *prometheus.HistogramVec) { + duration := time.Since(start) + counter.With(labels).Add(duration.Seconds()) + hist.With(labels).Observe(duration.Seconds()) +} + +// nolint +// TODO: add description +func HandleError(labels prometheus.Labels, err error, counter *prometheus.CounterVec) error { + errLabels := make(prometheus.Labels) + for k, v := range labels { + errLabels[k] = v + } + errLabels["error"] = err.Error() + counter.With(errLabels).Inc() + return err +} diff --git a/mocks/Change.go b/mocks/Change.go new file mode 100644 index 0000000000000000000000000000000000000000..d9f014299831206d664acce3714019c61d0d3f32 --- /dev/null +++ b/mocks/Change.go @@ -0,0 +1,89 @@ +// Code generated by mockery v2.9.4. DO NOT EDIT. + +package mocks + +import ( + pnd "code.fbi.h-da.de/danet/api/go/gosdn/pnd" + mock "github.com/stretchr/testify/mock" + + time "time" + + uuid "github.com/google/uuid" +) + +// Change is an autogenerated mock type for the Change type +type Change struct { + mock.Mock +} + +// Age provides a mock function with given fields: +func (_m *Change) Age() time.Duration { + ret := _m.Called() + + var r0 time.Duration + if rf, ok := ret.Get(0).(func() time.Duration); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(time.Duration) + } + + return r0 +} + +// Commit provides a mock function with given fields: +func (_m *Change) Commit() error { + ret := _m.Called() + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Confirm provides a mock function with given fields: +func (_m *Change) Confirm() error { + ret := _m.Called() + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// ID provides a mock function with given fields: +func (_m *Change) ID() uuid.UUID { + ret := _m.Called() + + var r0 uuid.UUID + if rf, ok := ret.Get(0).(func() uuid.UUID); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(uuid.UUID) + } + } + + return r0 +} + +// State provides a mock function with given fields: +func (_m *Change) State() pnd.Change_State { + ret := _m.Called() + + var r0 pnd.Change_State + if rf, ok := ret.Get(0).(func() pnd.Change_State); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(pnd.Change_State) + } + + return r0 +} diff --git a/mocks/ConfigCallback.go b/mocks/ConfigCallback.go deleted file mode 100644 index 36173a9d7ae5bafba95cff07a023db983ab80db0..0000000000000000000000000000000000000000 --- a/mocks/ConfigCallback.go +++ /dev/null @@ -1,27 +0,0 @@ -// Code generated by mockery v2.6.0. DO NOT EDIT. - -package mocks - -import ( - ygot "github.com/openconfig/ygot/ygot" - mock "github.com/stretchr/testify/mock" -) - -// ConfigCallback is an autogenerated mock type for the ConfigCallback type -type ConfigCallback struct { - mock.Mock -} - -// Execute provides a mock function with given fields: _a0 -func (_m *ConfigCallback) Execute(_a0 ygot.ValidatedGoStruct) error { - ret := _m.Called(_a0) - - var r0 error - if rf, ok := ret.Get(0).(func(ygot.ValidatedGoStruct) error); ok { - r0 = rf(_a0) - } else { - r0 = ret.Error(0) - } - - return r0 -} diff --git a/mocks/Device.go b/mocks/Device.go new file mode 100644 index 0000000000000000000000000000000000000000..ce8fd9c174c8f01da839e8e4a86491ef6f044243 --- /dev/null +++ b/mocks/Device.go @@ -0,0 +1,112 @@ +// Code generated by mockery v2.9.4. DO NOT EDIT. + +package mocks + +import ( + southbound "code.fbi.h-da.de/danet/gosdn/interfaces/southbound" + mock "github.com/stretchr/testify/mock" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + + transport "code.fbi.h-da.de/danet/gosdn/interfaces/transport" + + uuid "github.com/google/uuid" + + ygot "github.com/openconfig/ygot/ygot" +) + +// Device is an autogenerated mock type for the Device type +type Device struct { + mock.Mock +} + +// ID provides a mock function with given fields: +func (_m *Device) ID() uuid.UUID { + ret := _m.Called() + + var r0 uuid.UUID + if rf, ok := ret.Get(0).(func() uuid.UUID); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(uuid.UUID) + } + } + + return r0 +} + +// Model provides a mock function with given fields: +func (_m *Device) Model() ygot.GoStruct { + ret := _m.Called() + + var r0 ygot.GoStruct + if rf, ok := ret.Get(0).(func() ygot.GoStruct); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(ygot.GoStruct) + } + } + + return r0 +} + +// Name provides a mock function with given fields: +func (_m *Device) Name() string { + ret := _m.Called() + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +// ProcessResponse provides a mock function with given fields: _a0 +func (_m *Device) ProcessResponse(_a0 protoreflect.ProtoMessage) error { + ret := _m.Called(_a0) + + var r0 error + if rf, ok := ret.Get(0).(func(protoreflect.ProtoMessage) error); ok { + r0 = rf(_a0) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// SBI provides a mock function with given fields: +func (_m *Device) SBI() southbound.SouthboundInterface { + ret := _m.Called() + + var r0 southbound.SouthboundInterface + if rf, ok := ret.Get(0).(func() southbound.SouthboundInterface); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(southbound.SouthboundInterface) + } + } + + return r0 +} + +// Transport provides a mock function with given fields: +func (_m *Device) Transport() transport.Transport { + ret := _m.Called() + + var r0 transport.Transport + if rf, ok := ret.Get(0).(func() transport.Transport); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(transport.Transport) + } + } + + return r0 +} diff --git a/mocks/EscapeFunc.go b/mocks/EscapeFunc.go deleted file mode 100644 index 3ab84b3e650e7bad1fb3e88f2f0f7d02bee2abb1..0000000000000000000000000000000000000000 --- a/mocks/EscapeFunc.go +++ /dev/null @@ -1,24 +0,0 @@ -// Code generated by mockery v2.6.0. DO NOT EDIT. - -package mocks - -import mock "github.com/stretchr/testify/mock" - -// EscapeFunc is an autogenerated mock type for the EscapeFunc type -type EscapeFunc struct { - mock.Mock -} - -// Execute provides a mock function with given fields: k -func (_m *EscapeFunc) Execute(k string) string { - ret := _m.Called(k) - - var r0 string - if rf, ok := ret.Get(0).(func(string) string); ok { - r0 = rf(k) - } else { - r0 = ret.Get(0).(string) - } - - return r0 -} diff --git a/mocks/GNMIClient.go b/mocks/GNMIClient.go index 255d4a40d68513d1b1125101f8e9cdc12f139dc2..556bb65df2d7dd1a1605a16b984ba39cbe5e08ab 100644 --- a/mocks/GNMIClient.go +++ b/mocks/GNMIClient.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.6.0. DO NOT EDIT. +// Code generated by mockery 2.7.5. DO NOT EDIT. package mocks diff --git a/mocks/GNMIServer.go b/mocks/GNMIServer.go index 0628c5b31fe2c971810f5a2c9f7be3a8326ee40c..47dfbd15510c27896f0cb201999992816dfdeb59 100644 --- a/mocks/GNMIServer.go +++ b/mocks/GNMIServer.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.6.0. DO NOT EDIT. +// Code generated by mockery 2.7.5. DO NOT EDIT. package mocks diff --git a/mocks/GNMI_SubscribeClient.go b/mocks/GNMI_SubscribeClient.go index 456be898e5d92171a26add0d03e863f08f302d24..0d58afc80bc054a8c8f94dd8b27e5864e86239a4 100644 --- a/mocks/GNMI_SubscribeClient.go +++ b/mocks/GNMI_SubscribeClient.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.6.0. DO NOT EDIT. +// Code generated by mockery 2.7.5. DO NOT EDIT. package mocks diff --git a/mocks/GNMI_SubscribeServer.go b/mocks/GNMI_SubscribeServer.go index e19a9379ffc57345b30141b757dbd5d57327a82a..f663f552a3acb72cf00e011c0d557450bcca45a3 100644 --- a/mocks/GNMI_SubscribeServer.go +++ b/mocks/GNMI_SubscribeServer.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.6.0. DO NOT EDIT. +// Code generated by mockery 2.7.5. DO NOT EDIT. package mocks diff --git a/mocks/JSONUnmarshaler.go b/mocks/JSONUnmarshaler.go deleted file mode 100644 index 15dd0529058297459efe0de40d6264846bb03586..0000000000000000000000000000000000000000 --- a/mocks/JSONUnmarshaler.go +++ /dev/null @@ -1,36 +0,0 @@ -// Code generated by mockery v2.6.0. DO NOT EDIT. - -package mocks - -import ( - ygot "github.com/openconfig/ygot/ygot" - mock "github.com/stretchr/testify/mock" - - ytypes "github.com/openconfig/ygot/ytypes" -) - -// JSONUnmarshaler is an autogenerated mock type for the JSONUnmarshaler type -type JSONUnmarshaler struct { - mock.Mock -} - -// Execute provides a mock function with given fields: _a0, _a1, _a2 -func (_m *JSONUnmarshaler) Execute(_a0 []byte, _a1 ygot.GoStruct, _a2 ...ytypes.UnmarshalOpt) error { - _va := make([]interface{}, len(_a2)) - for _i := range _a2 { - _va[_i] = _a2[_i] - } - var _ca []interface{} - _ca = append(_ca, _a0, _a1) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 error - if rf, ok := ret.Get(0).(func([]byte, ygot.GoStruct, ...ytypes.UnmarshalOpt) error); ok { - r0 = rf(_a0, _a1, _a2...) - } else { - r0 = ret.Error(0) - } - - return r0 -} diff --git a/mocks/NetworkDomain.go b/mocks/NetworkDomain.go new file mode 100644 index 0000000000000000000000000000000000000000..1a5caa12c6cba52f6f9fdadd56fee7a8a0c720f9 --- /dev/null +++ b/mocks/NetworkDomain.go @@ -0,0 +1,395 @@ +// Code generated by mockery v2.9.4. DO NOT EDIT. + +package mocks + +import ( + change "code.fbi.h-da.de/danet/gosdn/interfaces/change" + device "code.fbi.h-da.de/danet/gosdn/interfaces/device" + + mock "github.com/stretchr/testify/mock" + + pnd "code.fbi.h-da.de/danet/api/go/gosdn/pnd" + + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + + southbound "code.fbi.h-da.de/danet/gosdn/interfaces/southbound" + + store "code.fbi.h-da.de/danet/gosdn/interfaces/store" + + transport "code.fbi.h-da.de/danet/api/go/gosdn/transport" + + uuid "github.com/google/uuid" +) + +// NetworkDomain is an autogenerated mock type for the NetworkDomain type +type NetworkDomain struct { + mock.Mock +} + +// AddDevice provides a mock function with given fields: name, opts, sid +func (_m *NetworkDomain) AddDevice(name string, opts *transport.TransportOption, sid uuid.UUID) error { + ret := _m.Called(name, opts, sid) + + var r0 error + if rf, ok := ret.Get(0).(func(string, *transport.TransportOption, uuid.UUID) error); ok { + r0 = rf(name, opts, sid) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// AddDeviceFromStore provides a mock function with given fields: name, deviceUUID, opt, sid +func (_m *NetworkDomain) AddDeviceFromStore(name string, deviceUUID uuid.UUID, opt *transport.TransportOption, sid uuid.UUID) error { + ret := _m.Called(name, deviceUUID, opt, sid) + + var r0 error + if rf, ok := ret.Get(0).(func(string, uuid.UUID, *transport.TransportOption, uuid.UUID) error); ok { + r0 = rf(name, deviceUUID, opt, sid) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// AddSbi provides a mock function with given fields: s +func (_m *NetworkDomain) AddSbi(s southbound.SouthboundInterface) error { + ret := _m.Called(s) + + var r0 error + if rf, ok := ret.Get(0).(func(southbound.SouthboundInterface) error); ok { + r0 = rf(s) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// ChangeOND provides a mock function with given fields: _a0, operation, path, value +func (_m *NetworkDomain) ChangeOND(_a0 uuid.UUID, operation pnd.ApiOperation, path string, value ...string) (uuid.UUID, error) { + _va := make([]interface{}, len(value)) + for _i := range value { + _va[_i] = value[_i] + } + var _ca []interface{} + _ca = append(_ca, _a0, operation, path) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + var r0 uuid.UUID + if rf, ok := ret.Get(0).(func(uuid.UUID, pnd.ApiOperation, string, ...string) uuid.UUID); ok { + r0 = rf(_a0, operation, path, value...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(uuid.UUID) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(uuid.UUID, pnd.ApiOperation, string, ...string) error); ok { + r1 = rf(_a0, operation, path, value...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Commit provides a mock function with given fields: _a0 +func (_m *NetworkDomain) Commit(_a0 uuid.UUID) error { + ret := _m.Called(_a0) + + var r0 error + if rf, ok := ret.Get(0).(func(uuid.UUID) error); ok { + r0 = rf(_a0) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// CommittedChanges provides a mock function with given fields: +func (_m *NetworkDomain) CommittedChanges() []uuid.UUID { + ret := _m.Called() + + var r0 []uuid.UUID + if rf, ok := ret.Get(0).(func() []uuid.UUID); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]uuid.UUID) + } + } + + return r0 +} + +// Confirm provides a mock function with given fields: _a0 +func (_m *NetworkDomain) Confirm(_a0 uuid.UUID) error { + ret := _m.Called(_a0) + + var r0 error + if rf, ok := ret.Get(0).(func(uuid.UUID) error); ok { + r0 = rf(_a0) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// ContainsDevice provides a mock function with given fields: _a0 +func (_m *NetworkDomain) ContainsDevice(_a0 uuid.UUID) bool { + ret := _m.Called(_a0) + + var r0 bool + if rf, ok := ret.Get(0).(func(uuid.UUID) bool); ok { + r0 = rf(_a0) + } else { + r0 = ret.Get(0).(bool) + } + + return r0 +} + +// Destroy provides a mock function with given fields: +func (_m *NetworkDomain) Destroy() error { + ret := _m.Called() + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Devices provides a mock function with given fields: +func (_m *NetworkDomain) Devices() []uuid.UUID { + ret := _m.Called() + + var r0 []uuid.UUID + if rf, ok := ret.Get(0).(func() []uuid.UUID); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]uuid.UUID) + } + } + + return r0 +} + +// GetChange provides a mock function with given fields: _a0 +func (_m *NetworkDomain) GetChange(_a0 uuid.UUID) (change.Change, error) { + ret := _m.Called(_a0) + + var r0 change.Change + if rf, ok := ret.Get(0).(func(uuid.UUID) change.Change); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(change.Change) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(uuid.UUID) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetDescription provides a mock function with given fields: +func (_m *NetworkDomain) GetDescription() string { + ret := _m.Called() + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +// GetDevice provides a mock function with given fields: identifier +func (_m *NetworkDomain) GetDevice(identifier string) (device.Device, error) { + ret := _m.Called(identifier) + + var r0 device.Device + if rf, ok := ret.Get(0).(func(string) device.Device); ok { + r0 = rf(identifier) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(device.Device) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(string) error); ok { + r1 = rf(identifier) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetName provides a mock function with given fields: +func (_m *NetworkDomain) GetName() string { + ret := _m.Called() + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +// GetSBIs provides a mock function with given fields: +func (_m *NetworkDomain) GetSBIs() store.Store { + ret := _m.Called() + + var r0 store.Store + if rf, ok := ret.Get(0).(func() store.Store); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(store.Store) + } + } + + return r0 +} + +// ID provides a mock function with given fields: +func (_m *NetworkDomain) ID() uuid.UUID { + ret := _m.Called() + + var r0 uuid.UUID + if rf, ok := ret.Get(0).(func() uuid.UUID); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(uuid.UUID) + } + } + + return r0 +} + +// MarshalDevice provides a mock function with given fields: _a0 +func (_m *NetworkDomain) MarshalDevice(_a0 string) (string, error) { + ret := _m.Called(_a0) + + var r0 string + if rf, ok := ret.Get(0).(func(string) string); ok { + r0 = rf(_a0) + } else { + r0 = ret.Get(0).(string) + } + + var r1 error + if rf, ok := ret.Get(1).(func(string) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PendingChanges provides a mock function with given fields: +func (_m *NetworkDomain) PendingChanges() []uuid.UUID { + ret := _m.Called() + + var r0 []uuid.UUID + if rf, ok := ret.Get(0).(func() []uuid.UUID); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]uuid.UUID) + } + } + + return r0 +} + +// RemoveDevice provides a mock function with given fields: _a0 +func (_m *NetworkDomain) RemoveDevice(_a0 uuid.UUID) error { + ret := _m.Called(_a0) + + var r0 error + if rf, ok := ret.Get(0).(func(uuid.UUID) error); ok { + r0 = rf(_a0) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// RemoveSbi provides a mock function with given fields: _a0 +func (_m *NetworkDomain) RemoveSbi(_a0 uuid.UUID) error { + ret := _m.Called(_a0) + + var r0 error + if rf, ok := ret.Get(0).(func(uuid.UUID) error); ok { + r0 = rf(_a0) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Request provides a mock function with given fields: _a0, _a1 +func (_m *NetworkDomain) Request(_a0 uuid.UUID, _a1 string) (protoreflect.ProtoMessage, error) { + ret := _m.Called(_a0, _a1) + + var r0 protoreflect.ProtoMessage + if rf, ok := ret.Get(0).(func(uuid.UUID, string) protoreflect.ProtoMessage); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(protoreflect.ProtoMessage) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(uuid.UUID, string) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// RequestAll provides a mock function with given fields: _a0 +func (_m *NetworkDomain) RequestAll(_a0 string) error { + ret := _m.Called(_a0) + + var r0 error + if rf, ok := ret.Get(0).(func(string) error); ok { + r0 = rf(_a0) + } else { + r0 = ret.Error(0) + } + + return r0 +} diff --git a/mocks/PrincipalNetworkDomain.go b/mocks/PrincipalNetworkDomain.go deleted file mode 100644 index 38233e76794d9913cf722aa848b2409fe4e1e499..0000000000000000000000000000000000000000 --- a/mocks/PrincipalNetworkDomain.go +++ /dev/null @@ -1,207 +0,0 @@ -// Code generated by mockery v2.6.0. DO NOT EDIT. - -package mocks - -import ( - mock "github.com/stretchr/testify/mock" - - uuid "github.com/google/uuid" -) - -// PrincipalNetworkDomain is an autogenerated mock type for the PrincipalNetworkDomain type -type PrincipalNetworkDomain struct { - mock.Mock -} - -// AddDevice provides a mock function with given fields: _a0 -func (_m *PrincipalNetworkDomain) AddDevice(_a0 interface{}) error { - ret := _m.Called(_a0) - - var r0 error - if rf, ok := ret.Get(0).(func(interface{}) error); ok { - r0 = rf(_a0) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// AddSbi provides a mock function with given fields: _a0 -func (_m *PrincipalNetworkDomain) AddSbi(_a0 interface{}) error { - ret := _m.Called(_a0) - - var r0 error - if rf, ok := ret.Get(0).(func(interface{}) error); ok { - r0 = rf(_a0) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// ContainsDevice provides a mock function with given fields: _a0 -func (_m *PrincipalNetworkDomain) ContainsDevice(_a0 uuid.UUID) bool { - ret := _m.Called(_a0) - - var r0 bool - if rf, ok := ret.Get(0).(func(uuid.UUID) bool); ok { - r0 = rf(_a0) - } else { - r0 = ret.Get(0).(bool) - } - - return r0 -} - -// Destroy provides a mock function with given fields: -func (_m *PrincipalNetworkDomain) Destroy() error { - ret := _m.Called() - - var r0 error - if rf, ok := ret.Get(0).(func() error); ok { - r0 = rf() - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// GetDescription provides a mock function with given fields: -func (_m *PrincipalNetworkDomain) GetDescription() string { - ret := _m.Called() - - var r0 string - if rf, ok := ret.Get(0).(func() string); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(string) - } - - return r0 -} - -// GetName provides a mock function with given fields: -func (_m *PrincipalNetworkDomain) GetName() string { - ret := _m.Called() - - var r0 string - if rf, ok := ret.Get(0).(func() string); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(string) - } - - return r0 -} - -// GetSBIs provides a mock function with given fields: -func (_m *PrincipalNetworkDomain) GetSBIs() interface{} { - ret := _m.Called() - - var r0 interface{} - if rf, ok := ret.Get(0).(func() interface{}); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(interface{}) - } - } - - return r0 -} - -// Id provides a mock function with given fields: -func (_m *PrincipalNetworkDomain) ID() uuid.UUID { - ret := _m.Called() - - var r0 uuid.UUID - if rf, ok := ret.Get(0).(func() uuid.UUID); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(uuid.UUID) - } - } - - return r0 -} - -// MarshalDevice provides a mock function with given fields: _a0 -func (_m *PrincipalNetworkDomain) MarshalDevice(_a0 uuid.UUID) (string, error) { - ret := _m.Called(_a0) - - var r0 string - if rf, ok := ret.Get(0).(func(uuid.UUID) string); ok { - r0 = rf(_a0) - } else { - r0 = ret.Get(0).(string) - } - - var r1 error - if rf, ok := ret.Get(1).(func(uuid.UUID) error); ok { - r1 = rf(_a0) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// RemoveDevice provides a mock function with given fields: _a0 -func (_m *PrincipalNetworkDomain) RemoveDevice(_a0 uuid.UUID) error { - ret := _m.Called(_a0) - - var r0 error - if rf, ok := ret.Get(0).(func(uuid.UUID) error); ok { - r0 = rf(_a0) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// RemoveSbi provides a mock function with given fields: _a0 -func (_m *PrincipalNetworkDomain) RemoveSbi(_a0 uuid.UUID) error { - ret := _m.Called(_a0) - - var r0 error - if rf, ok := ret.Get(0).(func(uuid.UUID) error); ok { - r0 = rf(_a0) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// Request provides a mock function with given fields: _a0, _a1 -func (_m *PrincipalNetworkDomain) Request(_a0 uuid.UUID, _a1 string) error { - ret := _m.Called(_a0, _a1) - - var r0 error - if rf, ok := ret.Get(0).(func(uuid.UUID, string) error); ok { - r0 = rf(_a0, _a1) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// RequestAll provides a mock function with given fields: _a0 -func (_m *PrincipalNetworkDomain) RequestAll(_a0 string) error { - ret := _m.Called(_a0) - - var r0 error - if rf, ok := ret.Get(0).(func(string) error); ok { - r0 = rf(_a0) - } else { - r0 = ret.Error(0) - } - - return r0 -} diff --git a/mocks/PublishFunc.go b/mocks/PublishFunc.go deleted file mode 100644 index 9bafd22090b46cd8a0b9d9aedcb5d502b340911b..0000000000000000000000000000000000000000 --- a/mocks/PublishFunc.go +++ /dev/null @@ -1,18 +0,0 @@ -// Code generated by mockery v2.6.0. DO NOT EDIT. - -package mocks - -import ( - mock "github.com/stretchr/testify/mock" - protoiface "google.golang.org/protobuf/runtime/protoiface" -) - -// PublishFunc is an autogenerated mock type for the PublishFunc type -type PublishFunc struct { - mock.Mock -} - -// Execute provides a mock function with given fields: addr, message -func (_m *PublishFunc) Execute(addr string, message protoiface.MessageV1) { - _m.Called(addr, message) -} diff --git a/mocks/SBIGreeter.go b/mocks/SBIGreeter.go deleted file mode 100644 index 7b7c999166b64bdf711da1b7ddb8e5801e9330fc..0000000000000000000000000000000000000000 --- a/mocks/SBIGreeter.go +++ /dev/null @@ -1,15 +0,0 @@ -// Code generated by mockery v2.6.0. DO NOT EDIT. - -package mocks - -import mock "github.com/stretchr/testify/mock" - -// SBIGreeter is an autogenerated mock type for the SBIGreeter type -type SBIGreeter struct { - mock.Mock -} - -// SBIHello provides a mock function with given fields: -func (_m *SBIGreeter) SBIHello() { - _m.Called() -} diff --git a/mocks/SouthboundInterface.go b/mocks/SouthboundInterface.go index 6217f5a7674db004f64254bfe5d5c8348ac733a7..22dd94e9ef59d87afb370f2a09f2fa4642b53de9 100644 --- a/mocks/SouthboundInterface.go +++ b/mocks/SouthboundInterface.go @@ -1,15 +1,19 @@ -// Code generated by mockery v2.6.0. DO NOT EDIT. +// Code generated by mockery v2.9.4. DO NOT EDIT. package mocks import ( + gosdnsouthbound "code.fbi.h-da.de/danet/api/go/gosdn/southbound" gnmi "github.com/openconfig/gnmi/proto/gnmi" + mock "github.com/stretchr/testify/mock" uuid "github.com/google/uuid" yang "github.com/openconfig/goyang/pkg/yang" + ygot "github.com/openconfig/ygot/ygot" + ytypes "github.com/openconfig/ygot/ytypes" ) @@ -18,7 +22,7 @@ type SouthboundInterface struct { mock.Mock } -// Id provides a mock function with given fields: +// ID provides a mock function with given fields: func (_m *SouthboundInterface) ID() uuid.UUID { ret := _m.Called() @@ -64,17 +68,57 @@ func (_m *SouthboundInterface) Schema() *ytypes.Schema { return r0 } -// SetNode provides a mock function with given fields: -func (_m *SouthboundInterface) SetNode() func(*yang.Entry, interface{}, *gnmi.Path, interface{}, []ytypes.SetNodeOpt) error { +// SetNode provides a mock function with given fields: schema, root, path, val, opts +func (_m *SouthboundInterface) SetNode(schema *yang.Entry, root interface{}, path *gnmi.Path, val interface{}, opts ...ytypes.SetNodeOpt) error { + _va := make([]interface{}, len(opts)) + for _i := range opts { + _va[_i] = opts[_i] + } + var _ca []interface{} + _ca = append(_ca, schema, root, path, val) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + var r0 error + if rf, ok := ret.Get(0).(func(*yang.Entry, interface{}, *gnmi.Path, interface{}, ...ytypes.SetNodeOpt) error); ok { + r0 = rf(schema, root, path, val, opts...) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Type provides a mock function with given fields: +func (_m *SouthboundInterface) Type() gosdnsouthbound.Type { ret := _m.Called() - var r0 func(*yang.Entry, interface{}, *gnmi.Path, interface{}, []ytypes.SetNodeOpt) error - if rf, ok := ret.Get(0).(func() func(*yang.Entry, interface{}, *gnmi.Path, interface{}, []ytypes.SetNodeOpt) error); ok { + var r0 gosdnsouthbound.Type + if rf, ok := ret.Get(0).(func() gosdnsouthbound.Type); ok { r0 = rf() } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(func(*yang.Entry, interface{}, *gnmi.Path, interface{}, []ytypes.SetNodeOpt) error) - } + r0 = ret.Get(0).(gosdnsouthbound.Type) + } + + return r0 +} + +// Unmarshal provides a mock function with given fields: _a0, _a1, _a2, _a3 +func (_m *SouthboundInterface) Unmarshal(_a0 []byte, _a1 *gnmi.Path, _a2 ygot.ValidatedGoStruct, _a3 ...ytypes.UnmarshalOpt) error { + _va := make([]interface{}, len(_a3)) + for _i := range _a3 { + _va[_i] = _a3[_i] + } + var _ca []interface{} + _ca = append(_ca, _a0, _a1, _a2) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + var r0 error + if rf, ok := ret.Get(0).(func([]byte, *gnmi.Path, ygot.ValidatedGoStruct, ...ytypes.UnmarshalOpt) error); ok { + r0 = rf(_a0, _a1, _a2, _a3...) + } else { + r0 = ret.Error(0) } return r0 diff --git a/mocks/Storable.go b/mocks/Storable.go index 630f70145d05ec4878461e243d238fe59958a483..e00e47c4b8f687d671e714deb3e22088b1ddc47c 100644 --- a/mocks/Storable.go +++ b/mocks/Storable.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.6.0. DO NOT EDIT. +// Code generated by mockery v2.9.4. DO NOT EDIT. package mocks @@ -13,7 +13,7 @@ type Storable struct { mock.Mock } -// Id provides a mock function with given fields: +// ID provides a mock function with given fields: func (_m *Storable) ID() uuid.UUID { ret := _m.Called() diff --git a/mocks/Store.go b/mocks/Store.go new file mode 100644 index 0000000000000000000000000000000000000000..308c2dd2222ff698b6ebbc8fc56301ec51364b6a --- /dev/null +++ b/mocks/Store.go @@ -0,0 +1,95 @@ +// Code generated by mockery v2.9.4. DO NOT EDIT. + +package mocks + +import ( + store "code.fbi.h-da.de/danet/gosdn/interfaces/store" + uuid "github.com/google/uuid" + mock "github.com/stretchr/testify/mock" +) + +// Store is an autogenerated mock type for the Store type +type Store struct { + mock.Mock +} + +// Add provides a mock function with given fields: item +func (_m *Store) Add(item store.Storable) error { + ret := _m.Called(item) + + var r0 error + if rf, ok := ret.Get(0).(func(store.Storable) error); ok { + r0 = rf(item) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Delete provides a mock function with given fields: id +func (_m *Store) Delete(id uuid.UUID) error { + ret := _m.Called(id) + + var r0 error + if rf, ok := ret.Get(0).(func(uuid.UUID) error); ok { + r0 = rf(id) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Exists provides a mock function with given fields: id +func (_m *Store) Exists(id uuid.UUID) bool { + ret := _m.Called(id) + + var r0 bool + if rf, ok := ret.Get(0).(func(uuid.UUID) bool); ok { + r0 = rf(id) + } else { + r0 = ret.Get(0).(bool) + } + + return r0 +} + +// Get provides a mock function with given fields: id +func (_m *Store) Get(id uuid.UUID) (store.Storable, error) { + ret := _m.Called(id) + + var r0 store.Storable + if rf, ok := ret.Get(0).(func(uuid.UUID) store.Storable); ok { + r0 = rf(id) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(store.Storable) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(uuid.UUID) error); ok { + r1 = rf(id) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// UUIDs provides a mock function with given fields: +func (_m *Store) UUIDs() []uuid.UUID { + ret := _m.Called() + + var r0 []uuid.UUID + if rf, ok := ret.Get(0).(func() []uuid.UUID); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]uuid.UUID) + } + } + + return r0 +} diff --git a/mocks/Transport.go b/mocks/Transport.go index 6dc256acae1ee730623be6ab1fd5508f9f4ed9f5..85653a57a49abf727461ca4885df9e9f0c9ea9f6 100644 --- a/mocks/Transport.go +++ b/mocks/Transport.go @@ -1,10 +1,12 @@ -// Code generated by mockery v2.6.0. DO NOT EDIT. +// Code generated by mockery v2.9.4. DO NOT EDIT. package mocks import ( context "context" + change "code.fbi.h-da.de/danet/gosdn/interfaces/change" + mock "github.com/stretchr/testify/mock" ytypes "github.com/openconfig/ygot/ytypes" @@ -45,22 +47,6 @@ func (_m *Transport) Get(ctx context.Context, params ...string) (interface{}, er return r0, r1 } -// GetOptions provides a mock function with given fields: -func (_m *Transport) GetOptions() interface{} { - ret := _m.Called() - - var r0 interface{} - if rf, ok := ret.Get(0).(func() interface{}); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(interface{}) - } - } - - return r0 -} - // ProcessResponse provides a mock function with given fields: resp, root, models func (_m *Transport) ProcessResponse(resp interface{}, root interface{}, models *ytypes.Schema) error { ret := _m.Called(resp, root, models) @@ -75,30 +61,18 @@ func (_m *Transport) ProcessResponse(resp interface{}, root interface{}, models return r0 } -// Set provides a mock function with given fields: ctx, params -func (_m *Transport) Set(ctx context.Context, params ...interface{}) (interface{}, error) { - var _ca []interface{} - _ca = append(_ca, ctx) - _ca = append(_ca, params...) - ret := _m.Called(_ca...) - - var r0 interface{} - if rf, ok := ret.Get(0).(func(context.Context, ...interface{}) interface{}); ok { - r0 = rf(ctx, params...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(interface{}) - } - } +// Set provides a mock function with given fields: ctx, payload +func (_m *Transport) Set(ctx context.Context, payload change.Payload) error { + ret := _m.Called(ctx, payload) - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, ...interface{}) error); ok { - r1 = rf(ctx, params...) + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, change.Payload) error); ok { + r0 = rf(ctx, payload) } else { - r1 = ret.Error(1) + r0 = ret.Error(0) } - return r0, r1 + return r0 } // Subscribe provides a mock function with given fields: ctx, params diff --git a/mocks/TransportOptions.go b/mocks/TransportOptions.go deleted file mode 100644 index 4893655f8a5bc0fef06e4898e116fc3df7171421..0000000000000000000000000000000000000000 --- a/mocks/TransportOptions.go +++ /dev/null @@ -1,57 +0,0 @@ -// Code generated by mockery v2.6.0. DO NOT EDIT. - -package mocks - -import mock "github.com/stretchr/testify/mock" - -// TransportOptions is an autogenerated mock type for the TransportOptions type -type TransportOptions struct { - mock.Mock -} - -// GetAddress provides a mock function with given fields: -func (_m *TransportOptions) GetAddress() string { - ret := _m.Called() - - var r0 string - if rf, ok := ret.Get(0).(func() string); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(string) - } - - return r0 -} - -// GetPassword provides a mock function with given fields: -func (_m *TransportOptions) GetPassword() string { - ret := _m.Called() - - var r0 string - if rf, ok := ret.Get(0).(func() string); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(string) - } - - return r0 -} - -// GetUsername provides a mock function with given fields: -func (_m *TransportOptions) GetUsername() string { - ret := _m.Called() - - var r0 string - if rf, ok := ret.Get(0).(func() string); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(string) - } - - return r0 -} - -// IsTransportOption provides a mock function with given fields: -func (_m *TransportOptions) IsTransportOption() { - _m.Called() -} diff --git a/mocks/UnsafeGNMIServer.go b/mocks/UnsafeGNMIServer.go new file mode 100644 index 0000000000000000000000000000000000000000..377e2d1cdda4eff9764adc784825237c7f2f4356 --- /dev/null +++ b/mocks/UnsafeGNMIServer.go @@ -0,0 +1,15 @@ +// Code generated by mockery 2.7.5. DO NOT EDIT. + +package mocks + +import mock "github.com/stretchr/testify/mock" + +// UnsafeGNMIServer is an autogenerated mock type for the UnsafeGNMIServer type +type UnsafeGNMIServer struct { + mock.Mock +} + +// mustEmbedUnimplementedGNMIServer provides a mock function with given fields: +func (_m *UnsafeGNMIServer) mustEmbedUnimplementedGNMIServer() { + _m.Called() +} diff --git a/mocks/isSubscribeRequest_Request.go b/mocks/isSubscribeRequest_Request.go index 73f763981ed7bd4586787e88694c844885b2b843..b1b09e55db8d7b31bbd4b02d383bb45e786b1de6 100644 --- a/mocks/isSubscribeRequest_Request.go +++ b/mocks/isSubscribeRequest_Request.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.6.0. DO NOT EDIT. +// Code generated by mockery 2.7.5. DO NOT EDIT. package mocks diff --git a/mocks/isSubscribeResponse_Response.go b/mocks/isSubscribeResponse_Response.go index ba10966e2703113f5fc03233883022efb7843b4b..0f38e4ee6d5ccc28a7e13943de6434d6647e811f 100644 --- a/mocks/isSubscribeResponse_Response.go +++ b/mocks/isSubscribeResponse_Response.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.6.0. DO NOT EDIT. +// Code generated by mockery 2.7.5. DO NOT EDIT. package mocks diff --git a/mocks/isTypedValue_Value.go b/mocks/isTypedValue_Value.go index a49fc787f9dbe7f24023258d180371a5bcd42c7b..bc9ac6962403f9d2251accafaf295ad63ca36303 100644 --- a/mocks/isTypedValue_Value.go +++ b/mocks/isTypedValue_Value.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.6.0. DO NOT EDIT. +// Code generated by mockery 2.7.5. DO NOT EDIT. package mocks diff --git a/northbound/client/core.go b/northbound/client/core.go new file mode 100644 index 0000000000000000000000000000000000000000..9f98060bc0dd47a83b9051dab35cb70202810f4d --- /dev/null +++ b/northbound/client/core.go @@ -0,0 +1,17 @@ +package client + +import ( + pb "code.fbi.h-da.de/danet/api/go/gosdn/core" + "google.golang.org/grpc" +) + +// CoreClient returns a client for the gRPC Core service. It takes +// the address of the gRPC endpoint and optional grpc.DialOption +// as argument +func CoreClient(addr string, opts ...grpc.DialOption) (pb.CoreClient, error) { + conn, err := grpc.Dial(addr, opts...) + if err != nil { + return nil, err + } + return pb.NewCoreClient(conn), nil +} diff --git a/northbound/client/pnd.go b/northbound/client/pnd.go new file mode 100644 index 0000000000000000000000000000000000000000..2e369982816965d4a4bfb8c97f4b3da527eae406 --- /dev/null +++ b/northbound/client/pnd.go @@ -0,0 +1,17 @@ +package client + +import ( + ppb "code.fbi.h-da.de/danet/api/go/gosdn/pnd" + "google.golang.org/grpc" +) + +// PndClient returns a client for the gRPC PND service. It takes +// the address of the gRPC endpoint and optional grpc.DialOption +// as argument +func PndClient(addr string, opts ...grpc.DialOption) (ppb.PndClient, error) { + conn, err := grpc.Dial(addr, opts...) + if err != nil { + return nil, err + } + return ppb.NewPndClient(conn), nil +} diff --git a/northbound/server/core.go b/northbound/server/core.go new file mode 100644 index 0000000000000000000000000000000000000000..d32628cef77fc0c12fcf6a25928952b4b3ced1ed --- /dev/null +++ b/northbound/server/core.go @@ -0,0 +1,86 @@ +package server + +import ( + "context" + "time" + + pb "code.fbi.h-da.de/danet/api/go/gosdn/core" + ppb "code.fbi.h-da.de/danet/api/go/gosdn/pnd" + spb "code.fbi.h-da.de/danet/api/go/gosdn/southbound" + "code.fbi.h-da.de/danet/gosdn/metrics" + "code.fbi.h-da.de/danet/gosdn/nucleus" + "github.com/google/uuid" + "github.com/prometheus/client_golang/prometheus" +) + +type core struct { + pb.UnimplementedCoreServer +} + +func (s core) Get(ctx context.Context, request *pb.GetRequest) (*pb.GetResponse, error) { + labels := prometheus.Labels{"service": "core", "rpc": "get"} + start := metrics.StartHook(labels, grpcRequestsTotal) + defer metrics.FinishHook(labels, start, grpcRequestDurationSecondsTotal, grpcRequestDurationSeconds) + var pndList []uuid.UUID + switch request.All { + case true: + pndList = pndc.UUIDs() + default: + var err error + pndList, err = stringToUUID(request.Pid) + if err != nil { + return nil, handleRPCError(labels, err) + } + } + + pnds := make([]*ppb.PrincipalNetworkDomain, len(pndList)) + for i, id := range pndList { + pnd, err := pndc.GetPND(id) + if err != nil { + return nil, err + } + + ond, err := fillOnds(pnd, true) + if err != nil { + return nil, handleRPCError(labels, err) + } + + sbi, err := fillSbis(pnd, true) + if err != nil { + return nil, handleRPCError(labels, err) + } + + pnds[i] = &ppb.PrincipalNetworkDomain{ + Id: pnd.ID().String(), + Name: pnd.GetName(), + Description: pnd.GetDescription(), + Ond: ond, + Sbi: sbi, + } + } + return &pb.GetResponse{ + Timestamp: time.Now().UnixNano(), + Pnd: pnds, + }, nil +} + +func (s core) Set(ctx context.Context, request *pb.SetRequest) (*pb.SetResponse, error) { + labels := prometheus.Labels{"service": "core", "rpc": "set"} + start := metrics.StartHook(labels, grpcRequestsTotal) + defer metrics.FinishHook(labels, start, grpcRequestDurationSecondsTotal, grpcRequestDurationSeconds) + for _, r := range request.Pnd { + sbi := nucleus.NewSBI(spb.Type_OPENCONFIG) + + pnd, err := nucleus.NewPND(r.Name, r.Description, uuid.New(), sbi, nil, nil) + if err != nil { + return nil, handleRPCError(labels, err) + } + if err := pndc.Add(pnd); err != nil { + return nil, handleRPCError(labels, err) + } + } + return &pb.SetResponse{ + Timestamp: time.Now().UnixNano(), + Status: pb.SetResponse_OK, + }, nil +} diff --git a/northbound/server/core_test.go b/northbound/server/core_test.go new file mode 100644 index 0000000000000000000000000000000000000000..efe46fd2a5dc67a6bda83a5c019c95afe62a51e1 --- /dev/null +++ b/northbound/server/core_test.go @@ -0,0 +1,124 @@ +package server + +import ( + "context" + "reflect" + "testing" + + pb "code.fbi.h-da.de/danet/api/go/gosdn/core" +) + +func Test_core_Set(t *testing.T) { + type args struct { + ctx context.Context + request *pb.SetRequest + } + tests := []struct { + name string + args args + want *pb.SetResponse + wantErr bool + }{ + { + name: "default", + args: args{ + ctx: context.Background(), + request: &pb.SetRequest{ + Pnd: []*pb.SetPnd{ + { + Name: "test", + Description: "test", + Sbi: "test", + }, + }, + }, + }, + want: &pb.SetResponse{}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + s := core{ + UnimplementedCoreServer: pb.UnimplementedCoreServer{}, + } + got, err := s.Set(tt.args.ctx, tt.args.request) + if (err != nil) != tt.wantErr { + t.Errorf("core.Set() error = %v, wantErr %v", err, tt.wantErr) + return + } + tt.want.Timestamp = got.Timestamp + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("core.Set() = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_core_Get(t *testing.T) { + type args struct { + ctx context.Context + request *pb.GetRequest + } + tests := []struct { + name string + args args + want []string + length int + wantErr bool + }{ + { + name: "default", + args: args{ + ctx: context.Background(), + request: &pb.GetRequest{ + Pid: []string{ + pndID, + }, + }, + }, + length: 1, + want: []string{ + pndID, + "test", + "test", + }, + }, + { + name: "getAll", + args: args{ + ctx: context.Background(), + request: &pb.GetRequest{ + All: true, + }, + }, + length: 2, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + s := core{ + UnimplementedCoreServer: pb.UnimplementedCoreServer{}, + } + resp, err := s.Get(tt.args.ctx, tt.args.request) + if (err != nil) != tt.wantErr { + t.Errorf("core.Get() error = %v, wantErr %v", err, tt.wantErr) + return + } + + if tt.name == "default" { + got := []string{ + resp.Pnd[0].Id, + resp.Pnd[0].Name, + resp.Pnd[0].Description, + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("core.Get() = %v, want %v", got, tt.want) + } + } + length := len(resp.Pnd) + if tt.length != length { + t.Errorf("core.Get() = %v, want %v", length, tt.length) + } + }) + } +} diff --git a/northbound/server/csbi.go b/northbound/server/csbi.go new file mode 100644 index 0000000000000000000000000000000000000000..b4d0e91dc86ef1ffba14c867fbb3e37507c9a371 --- /dev/null +++ b/northbound/server/csbi.go @@ -0,0 +1,61 @@ +package server + +import ( + "context" + "fmt" + "net" + "time" + + "github.com/prometheus/client_golang/prometheus" + log "github.com/sirupsen/logrus" + + cpb "code.fbi.h-da.de/danet/api/go/gosdn/csbi" + "code.fbi.h-da.de/danet/gosdn/metrics" + "code.fbi.h-da.de/danet/gosdn/store" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/peer" + "google.golang.org/grpc/status" +) + +type csbi struct { + cpb.UnimplementedCsbiServer +} + +func (s csbi) Hello(ctx context.Context, syn *cpb.Syn) (*cpb.Ack, error) { + labels := prometheus.Labels{"service": "csbi", "rpc": "hello"} + start := metrics.StartHook(labels, grpcRequestsTotal) + defer metrics.FinishHook(labels, start, grpcRequestDurationSecondsTotal, grpcRequestDurationSeconds) + ch, err := pndc.PendingChannels(store.FromString(syn.Id)) + if err != nil { + return nil, handleRPCError(labels, err) + } + p, ok := peer.FromContext(ctx) + if !ok { + e := fmt.Errorf("no peer information in context %v", ctx) + return nil, handleRPCError(labels, e) + } + csbiAddress, err := removePort(p.Addr) + if err != nil { + log.Error(err) + return nil, status.Errorf(codes.Aborted, "%v", err) + } + ch <- store.DeviceDetails{ + ID: syn.Id, + Address: net.JoinHostPort(csbiAddress, syn.Address), + } + details := <-ch + log.Infof("ack to csbi %v", syn.Id) + log.WithField("transport option", details.TransportOption).Debug("csbi ack transport options") + return &cpb.Ack{ + Timestamp: time.Now().UnixNano(), + TransportOption: details.TransportOption, + }, nil +} + +func removePort(ip net.Addr) (string, error) { + addr, ok := ip.(*net.TCPAddr) + if !ok { + return "", fmt.Errorf("invalid type assertion") + } + return addr.IP.String(), nil +} diff --git a/northbound/server/metrics.go b/northbound/server/metrics.go new file mode 100644 index 0000000000000000000000000000000000000000..742bc106c1cacff10c8854f5a94c6db841c5c9ff --- /dev/null +++ b/northbound/server/metrics.go @@ -0,0 +1,40 @@ +package server + +import ( + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" +) + +var ( + grpcRequestsTotal = promauto.NewCounterVec( + prometheus.CounterOpts{ + Name: "grpc_requests_total", + Help: "Total number of gRPC requests sent to the API", + }, + []string{"service", "rpc"}, + ) + + grpcAPIErrorsTotal = promauto.NewCounterVec( + prometheus.CounterOpts{ + Name: "grpc_api_errors_total", + Help: "Total number of errors returned by the API", + }, + []string{"service", "rpc", "error"}, + ) + + grpcRequestDurationSecondsTotal = promauto.NewCounterVec( + prometheus.CounterOpts{ + Name: "grpc_request_duration_seconds_total", + Help: "Cumulative time required to handle gRPC requests", + }, + []string{"service", "rpc"}, + ) + + grpcRequestDurationSeconds = promauto.NewHistogramVec( + prometheus.HistogramOpts{ + Name: "grpc_request_duration_seconds", + Help: "Histogram of gRPC request handling times", + }, + []string{"service", "rpc"}, + ) +) diff --git a/northbound/server/nbi.go b/northbound/server/nbi.go new file mode 100644 index 0000000000000000000000000000000000000000..22e257cdb4eda076aae41aefa0fd80352c7d48c6 --- /dev/null +++ b/northbound/server/nbi.go @@ -0,0 +1,35 @@ +package server + +import ( + "code.fbi.h-da.de/danet/gosdn/metrics" + "code.fbi.h-da.de/danet/gosdn/store" + "github.com/prometheus/client_golang/prometheus" + log "github.com/sirupsen/logrus" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +var pndc *store.PndStore + +// NorthboundInterface is the representation of the +// gRPC services used provided. +type NorthboundInterface struct { + Pnd *pndServer + Core *core + Csbi *csbi +} + +// NewNBI receives a PndStore and returns a new gRPC *NorthboundInterface +func NewNBI(pnds *store.PndStore) *NorthboundInterface { + pndc = pnds + return &NorthboundInterface{ + Pnd: &pndServer{}, + Core: &core{}, + Csbi: &csbi{}, + } +} + +func handleRPCError(labels prometheus.Labels, err error) error { + log.Error(err) + return status.Errorf(codes.Aborted, "%v", metrics.HandleError(labels, err, grpcAPIErrorsTotal)) +} diff --git a/northbound/server/pnd.go b/northbound/server/pnd.go new file mode 100644 index 0000000000000000000000000000000000000000..9392b2ef827f7ad8c6fee10ef57b12722971b65e --- /dev/null +++ b/northbound/server/pnd.go @@ -0,0 +1,429 @@ +package server + +import ( + "context" + "reflect" + "time" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + ppb "code.fbi.h-da.de/danet/api/go/gosdn/pnd" + spb "code.fbi.h-da.de/danet/api/go/gosdn/southbound" + "code.fbi.h-da.de/danet/gosdn/interfaces/networkdomain" + "code.fbi.h-da.de/danet/gosdn/metrics" + "code.fbi.h-da.de/danet/gosdn/nucleus/errors" + "github.com/google/uuid" + "github.com/openconfig/ygot/ygot" + "github.com/prometheus/client_golang/prometheus" + log "github.com/sirupsen/logrus" +) + +type pndServer struct { + ppb.UnimplementedPndServer +} + +func (p pndServer) Get(ctx context.Context, request *ppb.GetRequest) (*ppb.GetResponse, error) { + labels := prometheus.Labels{"service": "pnd", "rpc": "get"} + start := metrics.StartHook(labels, grpcRequestsTotal) + defer metrics.FinishHook(labels, start, grpcRequestDurationSecondsTotal, grpcRequestDurationSeconds) + pid, err := uuid.Parse(request.Pid) + if err != nil { + return nil, handleRPCError(labels, err) + } + switch req := request.Request.(type) { + case *ppb.GetRequest_Pnd: + return handleGetPnd(pid) + case *ppb.GetRequest_Ond: + return handleGetOnd(pid, req) + case *ppb.GetRequest_Sbi: + return handleGetSbi(pid, req) + case *ppb.GetRequest_Change: + return handleGetChange(pid, req) + case *ppb.GetRequest_Path: + return handleGetPath(pid, req) + default: + return nil, handleRPCError(labels, errors.ErrOperationNotSupported{Op: reflect.TypeOf(request.Request)}) + } +} + +func handleGetPnd(pid uuid.UUID) (*ppb.GetResponse, error) { + pnd, err := pndc.GetPND(pid) + if err != nil { + log.Error(err) + return nil, status.Errorf(codes.Aborted, "%v", err) + } + onds, err := fillOnds(pnd, true) + if err != nil { + log.Error(err) + return nil, status.Errorf(codes.Aborted, "%v", err) + } + sbis, err := fillSbis(pnd, true) + if err != nil { + log.Error(err) + return nil, status.Errorf(codes.Aborted, "%v", err) + } + changes, err := fillChanges(pnd, true) + if err != nil { + log.Error(err) + return nil, status.Errorf(codes.Aborted, "%v", err) + } + + return &ppb.GetResponse{ + Timestamp: time.Now().UnixNano(), + Pnd: &ppb.PrincipalNetworkDomain{ + Id: pnd.ID().String(), + Name: pnd.GetName(), + Description: pnd.GetDescription(), + Ond: onds, + Sbi: sbis, + Change: changes, + }, + }, nil +} + +func handleGetSbi(pid uuid.UUID, req *ppb.GetRequest_Sbi) (*ppb.GetResponse, error) { + pnd, err := pndc.GetPND(pid) + if err != nil { + log.Error(err) + return nil, status.Errorf(codes.Aborted, "%v", err) + } + sbis, err := fillSbis(pnd, req.Sbi.GetAll(), req.Sbi.Sid...) + if err != nil { + log.Error(err) + return nil, status.Errorf(codes.Aborted, "%v", err) + } + return &ppb.GetResponse{ + Timestamp: time.Now().UnixNano(), + Sbi: sbis, + }, nil +} + +func stringToUUID(sid []string) ([]uuid.UUID, error) { + UUIDs := make([]uuid.UUID, len(sid)) + for i, id := range sid { + parsed, err := uuid.Parse(id) + if err != nil { + log.Error(err) + return nil, status.Errorf(codes.Aborted, "%v", err) + } + UUIDs[i] = parsed + } + return UUIDs, nil +} + +func handleGetOnd(pid uuid.UUID, req *ppb.GetRequest_Ond) (*ppb.GetResponse, error) { + pnd, err := pndc.GetPND(pid) + if err != nil { + log.Error(err) + return nil, status.Errorf(codes.Aborted, "%v", err) + } + onds, err := fillOnds(pnd, req.Ond.All, req.Ond.Did...) + if err != nil { + log.Error(err) + return nil, status.Errorf(codes.Aborted, "%v", err) + } + return &ppb.GetResponse{ + Timestamp: time.Now().UnixNano(), + Ond: onds, + }, nil +} + +func handleGetChange(pid uuid.UUID, req *ppb.GetRequest_Change) (*ppb.GetResponse, error) { + pnd, err := pndc.GetPND(pid) + if err != nil { + log.Error(err) + return nil, status.Errorf(codes.Aborted, "%v", err) + } + changes, err := fillChanges(pnd, req.Change.All, req.Change.Cuid...) + if err != nil { + log.Error(err) + return nil, status.Errorf(codes.Aborted, "%v", err) + } + return &ppb.GetResponse{ + Timestamp: time.Now().UnixNano(), + Change: changes, + }, nil +} + +func handleGetPath(pid uuid.UUID, req *ppb.GetRequest_Path) (*ppb.GetResponse, error) { + pnd, err := pndc.GetPND(pid) + if err != nil { + log.Error(err) + return nil, status.Errorf(codes.Aborted, "%v", err) + } + duid, err := uuid.Parse(req.Path.Did) + if err != nil { + log.Error(err) + return nil, status.Errorf(codes.Aborted, "%v", err) + } + _, err = pnd.Request(duid, req.Path.Path) + if err != nil { + log.Error(err) + return nil, status.Errorf(codes.Aborted, "%v", err) + } + ond, err := fillOnds(pnd, false, req.Path.Did) + if err != nil { + log.Error(err) + return nil, status.Errorf(codes.Aborted, "%v", err) + } + return &ppb.GetResponse{ + Timestamp: time.Now().UnixNano(), + Ond: ond, + }, nil +} + +func fillSbis(pnd networkdomain.NetworkDomain, all bool, sid ...string) ([]*spb.SouthboundInterface, error) { + var sbiList []uuid.UUID + + sbiStore := pnd.GetSBIs() + switch all { + case true: + sbiList = sbiStore.UUIDs() + default: + var err error + if len(sid) == 0 { + return nil, &errors.ErrInvalidParameters{ + Func: fillSbis, + Param: "length of 'sid' cannot be '0' when 'all' is set to 'false'", + } + } + sbiList, err = stringToUUID(sid) + if err != nil { + log.Error(err) + return nil, status.Errorf(codes.Aborted, "%v", err) + } + } + sbis := make([]*spb.SouthboundInterface, len(sbiList)) + for i, id := range sbiList { + _, err := sbiStore.Get(id) + if err != nil { + log.Error(err) + return nil, status.Errorf(codes.Aborted, "%v", err) + } + sbis[i] = &spb.SouthboundInterface{ + Id: id.String(), + } + } + return sbis, nil +} + +func fillOnds(pnd networkdomain.NetworkDomain, all bool, did ...string) ([]*ppb.OrchestratedNetworkingDevice, error) { + var ondList []uuid.UUID + var onds []*ppb.OrchestratedNetworkingDevice + + // all indicates if a client wants all devices or only a single one + switch all { + case true: + ondList = pnd.Devices() + onds = make([]*ppb.OrchestratedNetworkingDevice, len(ondList)) + for _, id := range ondList { + did = append(did, id.String()) + } + default: + if len(did) == 0 { + err := &errors.ErrInvalidParameters{ + Func: fillOnds, + Param: "length of 'did' cannot be '0' when 'all' is set to 'false'", + } + log.Error(err) + + return nil, err + } + + onds = make([]*ppb.OrchestratedNetworkingDevice, 1) + } + + for i, id := range did { + d, err := pnd.GetDevice(id) + if err != nil { + log.Error(err) + return nil, status.Errorf(codes.Aborted, "%v", err) + } + cfg := ygot.GNMINotificationsConfig{} + dev, err := ygot.TogNMINotifications(d.Model(), time.Now().UnixNano(), cfg) + if err != nil { + log.Error(err) + return nil, status.Errorf(codes.Aborted, "%v", err) + } + onds[i] = &ppb.OrchestratedNetworkingDevice{ + Id: id, + Name: d.Name(), + Device: dev, + } + } + + return onds, nil +} + +func fillChanges(pnd networkdomain.NetworkDomain, all bool, cuid ...string) ([]*ppb.Change, error) { + var changeList []uuid.UUID + + switch all { + case true: + changeList = pnd.PendingChanges() + changeList = append(changeList, pnd.CommittedChanges()...) + default: + var err error + if len(cuid) == 0 { + return nil, &errors.ErrInvalidParameters{ + Func: fillOnds, + Param: "length of 'did' cannot be '0' when 'all' is set to 'false'", + } + } + changeList, err = stringToUUID(cuid) + if err != nil { + log.Error(err) + return nil, status.Errorf(codes.Aborted, "%v", err) + } + } + + changes := make([]*ppb.Change, len(changeList)) + for i, ch := range changeList { + c, err := pnd.GetChange(ch) + if err != nil { + log.Error(err) + return nil, status.Errorf(codes.Aborted, "%v", err) + } + + changes[i] = &ppb.Change{ + Id: ch.String(), + Age: c.Age().Microseconds(), + State: c.State(), + } + } + return changes, nil +} + +func (p pndServer) Set(ctx context.Context, request *ppb.SetRequest) (*ppb.SetResponse, error) { + labels := prometheus.Labels{"service": "pnd", "rpc": "set"} + start := metrics.StartHook(labels, grpcRequestsTotal) + defer metrics.FinishHook(labels, start, grpcRequestDurationSecondsTotal, grpcRequestDurationSeconds) + pid, err := uuid.Parse(request.Pid) + if err != nil { + return nil, handleRPCError(labels, err) + } + + pnd, err := pndc.GetPND(pid) + if err != nil { + return nil, handleRPCError(labels, err) + } + + ondResp, err := handleSetOnd(pnd, request.Ond) + if err != nil { + return nil, handleRPCError(labels, err) + } + changeResp, err := handleSetChange(pnd, request.Change) + if err != nil { + return nil, handleRPCError(labels, err) + } + changeRequestResp, err := handleChangeRequest(pnd, request.ChangeRequest) + if err != nil { + return nil, handleRPCError(labels, err) + } + return &ppb.SetResponse{ + Timestamp: time.Now().UnixNano(), + Status: ppb.SetResponse_OK, + Responses: []*ppb.SetResponse{ + ondResp, + changeResp, + changeRequestResp, + }, + }, nil +} + +func handleSetOnd(pnd networkdomain.NetworkDomain, req []*ppb.SetOnd) (*ppb.SetResponse, error) { + for _, r := range req { + sid, err := uuid.Parse(r.Sbi.Id) + if err != nil { + log.Error(err) + return nil, status.Errorf(codes.Aborted, "%v", err) + } + if err := pnd.AddDevice(r.DeviceName, r.TransportOption, sid); err != nil { + log.Error(err) + return nil, status.Errorf(codes.Aborted, "%v", err) + } + } + return &ppb.SetResponse{ + Timestamp: time.Now().UnixNano(), + Status: ppb.SetResponse_OK, + }, nil +} + +func handleSetChange(pnd networkdomain.NetworkDomain, req []*ppb.SetChange) (*ppb.SetResponse, error) { + for _, r := range req { + cuid, err := uuid.Parse(r.Cuid) + if err != nil { + log.Error(err) + return nil, status.Errorf(codes.Aborted, "%v", err) + } + switch r.Op { + case ppb.SetChange_COMMIT: + if err := pnd.Commit(cuid); err != nil { + log.Error(err) + return nil, status.Errorf(codes.Aborted, "%v", err) + } + case ppb.SetChange_CONFIRM: + if err := pnd.Confirm(cuid); err != nil { + log.Error(err) + return nil, status.Errorf(codes.Aborted, "%v", err) + } + default: + return nil, &errors.ErrInvalidParameters{ + Func: handleSetChange, + Param: r.Op, + } + } + } + return &ppb.SetResponse{ + Timestamp: time.Now().UnixNano(), + Status: ppb.SetResponse_OK, + }, nil +} + +func handleChangeRequest(pnd networkdomain.NetworkDomain, req []*ppb.ChangeRequest) (*ppb.SetResponse, error) { + for _, r := range req { + did, err := uuid.Parse(r.Id) + if err != nil { + log.Error(err) + return nil, status.Errorf(codes.Aborted, "%v", err) + } + // TODO: Return CUID in API + _, err = pnd.ChangeOND(did, r.ApiOp, r.Path, r.Value) + if err != nil { + log.Error(err) + return nil, status.Errorf(codes.Aborted, "%v", err) + } + } + return &ppb.SetResponse{ + Timestamp: time.Now().UnixNano(), + Status: ppb.SetResponse_OK, + }, nil +} + +func (p pndServer) Delete(ctx context.Context, req *ppb.DeleteRequest) (*ppb.DeleteResponse, error) { + pid, err := uuid.Parse(req.Pid) + if err != nil { + log.Error(err) + return nil, status.Errorf(codes.Aborted, "%v", err) + } + pnd, err := pndc.GetPND(pid) + if err != nil { + log.Error(err) + return nil, status.Errorf(codes.Aborted, "%v", err) + } + + did, err := uuid.Parse(req.Uuid) + if err != nil { + log.Error(err) + return nil, status.Errorf(codes.Aborted, "%v", err) + } + if err := pnd.RemoveDevice(did); err != nil { + log.Error(err) + return nil, status.Errorf(codes.Aborted, "%v", err) + } + return &ppb.DeleteResponse{ + Timestamp: time.Now().UnixNano(), + Status: ppb.DeleteResponse_OK, + }, nil +} diff --git a/northbound/server/pnd_test.go b/northbound/server/pnd_test.go new file mode 100644 index 0000000000000000000000000000000000000000..19e765819e84894daf50714d2856a5ecf7b78757 --- /dev/null +++ b/northbound/server/pnd_test.go @@ -0,0 +1,337 @@ +package server + +import ( + "context" + "os" + "reflect" + "testing" + "time" + + ppb "code.fbi.h-da.de/danet/api/go/gosdn/pnd" + spb "code.fbi.h-da.de/danet/api/go/gosdn/southbound" + "code.fbi.h-da.de/danet/api/go/gosdn/transport" + "code.fbi.h-da.de/danet/gosdn/interfaces/device" + "code.fbi.h-da.de/danet/gosdn/interfaces/networkdomain" + "code.fbi.h-da.de/danet/gosdn/mocks" + "code.fbi.h-da.de/danet/gosdn/nucleus" + "code.fbi.h-da.de/danet/gosdn/store" + "code.fbi.h-da.de/danet/yang-models/generated/openconfig" + "github.com/google/uuid" + log "github.com/sirupsen/logrus" + "github.com/stretchr/testify/mock" + "google.golang.org/grpc" + + cpb "code.fbi.h-da.de/danet/api/go/gosdn/csbi" +) + +const pndID = "2043519e-46d1-4963-9a8e-d99007e104b8" +const pendingChangeID = "0992d600-f7d4-4906-9559-409b04d59a5f" +const committedChangeID = "804787d6-e5a8-4dba-a1e6-e73f96b0119e" +const sbiID = "f6fd4b35-f039-4111-9156-5e4501bb8a5a" +const ondID = "7e0ed8cc-ebf5-46fa-9794-741494914883" + +var hostname = "manfred" +var pndUUID uuid.UUID +var sbiUUID uuid.UUID +var pendingChangeUUID uuid.UUID +var committedChangeUUID uuid.UUID +var deviceUUID uuid.UUID +var mockPnd *mocks.NetworkDomain +var mockDevice device.Device +var sbiStore *store.SbiStore + +func callback(id uuid.UUID, ch chan store.DeviceDetails) { + // Need for pnd creation, but not needed for this test case. +} + +func removeExistingStores() { + os.RemoveAll("stores/") +} + +func getMockPND() networkdomain.NetworkDomain { + sbi := nucleus.NewSBI(spb.Type(0), sbiUUID) + + conn, err := grpc.Dial("orchestrator", grpc.WithInsecure()) + if err != nil { + log.Fatal(err) + } + + csbiClient := cpb.NewCsbiClient(conn) + + newPnd, _ := nucleus.NewPND( + "test", + "test", + pndUUID, + sbi, + csbiClient, + callback, + ) + + newPnd.AddDeviceFromStore( + "test", + deviceUUID, + &transport.TransportOption{ + Address: "test", + Username: "test", + Password: "test", + TransportOption: &transport.TransportOption_GnmiTransportOption{ + GnmiTransportOption: &transport.GnmiTransportOption{}, + }, + Type: spb.Type_OPENCONFIG, + }, sbiUUID) + + return newPnd +} + +func TestMain(m *testing.M) { + removeExistingStores() + + log.SetReportCaller(true) + var err error + pndUUID, err = uuid.Parse(pndID) + if err != nil { + log.Fatal(err) + } + + sbiUUID, err = uuid.Parse(sbiID) + if err != nil { + log.Fatal(err) + } + + pendingChangeUUID, err = uuid.Parse(pendingChangeID) + if err != nil { + log.Fatal(err) + } + + committedChangeUUID, err = uuid.Parse(committedChangeID) + if err != nil { + log.Fatal(err) + } + + deviceUUID, err = uuid.Parse(ondID) + if err != nil { + log.Fatal(err) + } + + mockDevice = &nucleus.CommonDevice{ + GoStruct: &openconfig.Device{ + System: &openconfig.OpenconfigSystem_System{ + Config: &openconfig.OpenconfigSystem_System_Config{ + Hostname: &hostname, + }, + }, + }, + UUID: deviceUUID, + } + + mockDevice.(*nucleus.CommonDevice).SetSBI(nucleus.NewSBI(spb.Type_OPENCONFIG)) + mockDevice.(*nucleus.CommonDevice).SetTransport(&mocks.Transport{}) + mockDevice.(*nucleus.CommonDevice).SetName(hostname) + sbiStore = store.NewSbiStore() + if err := sbiStore.Add(mockDevice.SBI()); err != nil { + log.Fatal(err) + } + + mockChange := &mocks.Change{} + mockChange.On("Age").Return(time.Hour) + mockChange.On("State").Return(ppb.Change_INCONSISTENT) + + mockPnd = &mocks.NetworkDomain{} + mockPnd.On("ID").Return(pndUUID) + mockPnd.On("GetName").Return("test") + mockPnd.On("GetDescription").Return("test") + mockPnd.On("GetSBIs").Return(sbiStore) + mockPnd.On("Devices").Return([]uuid.UUID{deviceUUID}) + mockPnd.On("PendingChanges").Return([]uuid.UUID{pendingChangeUUID}) + mockPnd.On("CommittedChanges").Return([]uuid.UUID{committedChangeUUID}) + mockPnd.On("GetChange", mock.Anything).Return(mockChange, nil) + mockPnd.On("AddDevice", mock.Anything, mock.Anything, mock.Anything).Return(nil) + mockPnd.On("GetDevice", mock.Anything).Return(mockDevice, nil) + mockPnd.On("Commit", mock.Anything).Return(nil) + mockPnd.On("Confirm", mock.Anything).Return(nil) + mockPnd.On("ChangeOND", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(uuid.Nil, nil) + + newPnd := getMockPND() + + pndc = store.NewPndStore() + if err := pndc.Add(newPnd); err != nil { + log.Fatal(err) + } + + os.Exit(m.Run()) +} + +// TODO: We should re-add all tests for changes. +// As of now this is not possible as we can't use the mock pnd, as it can't be serialized because of +// cyclic use of mock in it. +func Test_pnd_Get(t *testing.T) { + removeExistingStores() + + type args struct { + ctx context.Context + request *ppb.GetRequest + } + tests := []struct { + name string + args args + want []string + wantErr bool + }{ + { + name: "get pnd", + args: args{ + ctx: context.Background(), + request: &ppb.GetRequest{ + Request: &ppb.GetRequest_Pnd{ + Pnd: &ppb.GetPnd{}, + }, + Pid: pndID, + }, + }, + want: []string{ + pndID, + ondID, + sbiID, + // pendingChangeID, + // committedChangeID, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := pndServer{ + UnimplementedPndServer: ppb.UnimplementedPndServer{}, + } + resp, err := p.Get(tt.args.ctx, tt.args.request) + if (err != nil) != tt.wantErr { + t.Errorf("Get() error = %v, wantErr %v", err, tt.wantErr) + return + } + + got := []string{ + resp.Pnd.Id, + resp.Pnd.Ond[0].Id, + resp.Pnd.Sbi[0].Id, + // resp.Pnd.Change[0].Id, + // resp.Pnd.Change[1].Id, + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("Get() got = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_pnd_Set(t *testing.T) { + removeExistingStores() + + type args struct { + ctx context.Context + request *ppb.SetRequest + } + tests := []struct { + name string + args args + want ppb.SetResponseStatus + wantErr bool + }{ + { + name: "set ond", + args: args{ + ctx: context.Background(), + request: &ppb.SetRequest{ + Ond: []*ppb.SetOnd{ + { + Sbi: &spb.SouthboundInterface{ + Id: sbiID, + Type: spb.Type_OPENCONFIG, + }, + DeviceName: hostname, + TransportOption: &transport.TransportOption{ + Address: "test", + Username: "test", + Password: "test", + TransportOption: &transport.TransportOption_GnmiTransportOption{ + GnmiTransportOption: &transport.GnmiTransportOption{}, + }, + }, + }, + }, + Pid: pndID, + }, + }, + want: ppb.SetResponse_OK, + }, + // { + // name: "set change", + // args: args{ + // ctx: context.Background(), + // request: &ppb.SetRequest{ + // Pid: pndID, + // Change: []*ppb.SetChange{ + // { + // Cuid: pendingChangeID, + // Op: ppb.SetChange_COMMIT, + // }, + // { + // Cuid: committedChangeID, + // Op: ppb.SetChange_CONFIRM, + // }, + // }, + // }, + // }, + // want: ppb.SetResponse_OK, + // }, + // { + // name: "change request", + // args: args{ + // ctx: context.Background(), + // request: &ppb.SetRequest{ + // Pid: pndID, + // ChangeRequest: []*ppb.ChangeRequest{ + // { + // Id: ondID, + // Path: "/system/config/hostname", + // Value: "herbert", + // ApiOp: ppb.ApiOperation_UPDATE, + // }, + // { + // Id: ondID, + // Path: "/system/config/hostname", + // Value: "fridolin", + // ApiOp: ppb.ApiOperation_REPLACE, + // }, + // { + // Id: ondID, + // Path: "/system/config/hostname", + // ApiOp: ppb.ApiOperation_DELETE, + // }, + // }, + // }, + // }, + // want: ppb.SetResponse_OK, + // }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := pndServer{ + UnimplementedPndServer: ppb.UnimplementedPndServer{}, + } + resp, err := p.Set(tt.args.ctx, tt.args.request) + if (err != nil) != tt.wantErr { + t.Errorf("Set() error = %v, wantErr %v", err, tt.wantErr) + return + } + got := resp.Status + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("Set() got = %v, want %v", got, tt.want) + } + for _, r := range resp.Responses { + got = r.Status + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("Set() got = %v, want %v", got, tt.want) + } + } + }) + } +} diff --git a/nucleus/change.go b/nucleus/change.go new file mode 100644 index 0000000000000000000000000000000000000000..ca4a6bd4bfcf43993995bc41139a1ff83ee0a09b --- /dev/null +++ b/nucleus/change.go @@ -0,0 +1,200 @@ +package nucleus + +import ( + "context" + "fmt" + "os" + "sync" + "time" + + ppb "code.fbi.h-da.de/danet/api/go/gosdn/pnd" + + "github.com/google/uuid" + "github.com/openconfig/ygot/ygot" + log "github.com/sirupsen/logrus" +) + +var changeTimeout time.Duration + +func init() { + var err error + e := os.Getenv("GOSDN_CHANGE_TIMEOUT") + if e != "" { + changeTimeout, err = time.ParseDuration(e) + if err != nil { + log.Fatal(err) + } + log.Debugf("change timeout set to %v", changeTimeout) + } else { + changeTimeout = time.Minute * 10 + } +} + +// NewChange takes a Device UUID, a pair GoStructs (current and intended state), +// a callback function, and returns a *Change. +// The callback function is used by the Commit() and Confirm() functions. It +// must define how the change is carried out. +func NewChange(device uuid.UUID, currentState ygot.GoStruct, change ygot.GoStruct, callback func(ygot.GoStruct, ygot.GoStruct) error) *Change { + c := &Change{ + cuid: uuid.New(), + duid: device, + state: ppb.Change_PENDING, + timestamp: time.Now(), + previousState: currentState, + intendedState: change, + callback: callback, + } + stateManagerCtx, stateManagerCancel := context.WithCancel(context.Background()) + stateIn, stateOut, errChan := stateManager(stateManagerCtx, c, changeTimeout) + c.stateIn = stateIn + c.stateOut = stateOut + c.errChan = errChan + c.stateManagerCancel = stateManagerCancel + return c +} + +// Change is an intended change to an OND. It is unique and immutable. +// It has a cuid, a timestamp, and holds both the previous and the new +// state. It keeps track if the state is committed and confirmed. A callback +// exists to acess the proper transport for the changed OND +type Change struct { + cuid uuid.UUID + duid uuid.UUID + state ppb.Change_State + timestamp time.Time + previousState ygot.GoStruct + intendedState ygot.GoStruct + callback func(ygot.GoStruct, ygot.GoStruct) error + stateMu sync.RWMutex + errChan <-chan error + stateIn chan<- ppb.Change_State + stateOut <-chan ppb.Change_State + stateManagerCancel context.CancelFunc +} + +// ID returns the Change's UUID +func (c *Change) ID() uuid.UUID { + return c.cuid +} + +// Commit pushes the change to the OND using the callback() function +// and starts the timeout-timer for the Change. If the timer expires +// the change is rolled back. +func (c *Change) Commit() error { + //TODO: check if already commited + c.stateIn <- ppb.Change_COMMITTED + select { + case err := <-c.errChan: + return err + case <-c.stateOut: + return nil + } +} + +// Confirm confirms a committed Change and stops the rollback timer. +func (c *Change) Confirm() error { + //TODO: check if already confirmed + c.stateIn <- ppb.Change_CONFIRMED + select { + case err := <-c.errChan: + return err + case <-c.stateOut: + return nil + } +} + +// Age returns the passed time since the Change was created +func (c *Change) Age() time.Duration { + return time.Since(c.timestamp) +} + +// State returns the changes's state. +func (c *Change) State() ppb.Change_State { + c.stateMu.RLock() + state := c.state + c.stateMu.RUnlock() + return state +} + +func stateManager(ctx context.Context, ch *Change, timeout time.Duration) (chan<- ppb.Change_State, <-chan ppb.Change_State, <-chan error) { + stateIn := make(chan ppb.Change_State) + stateOut := make(chan ppb.Change_State) + // A Goroutine, which is created while a new Change is initialized acts as + // the reciever for errorChan + errChan := make(chan error) + // create ticker and make it wait for 1 week + // workaround for delayed ticker start and ugly housekeeping + ticker := time.NewTicker(time.Hour * 7 * 24) + ticker.Stop() + + go func() { + running: + for { + //TODO: priority select? should ticker have priority? + select { + case <-ticker.C: + state := ch.State() + if state == ppb.Change_CONFIRMED { + continue + } + err := ch.callback(ch.intendedState, ch.previousState) + if err != nil { + ch.stateMu.Lock() + ch.state = ppb.Change_INCONSISTENT + ch.stateMu.Unlock() + log.Errorf("change %v timed out", ch.cuid) + log.Error(err) + continue + } + // A rollback has been executed and the timer is stopped + ticker.Stop() + // TODO: keep the Change as pending, or remove it? + ch.stateMu.Lock() + ch.state = ppb.Change_PENDING + ch.stateMu.Unlock() + log.Errorf("change %v timed out", ch.cuid) + case s := <-stateIn: + switch s { + case ppb.Change_COMMITTED: + state := ch.State() + if state == ppb.Change_COMMITTED || state == ppb.Change_CONFIRMED { + errChan <- fmt.Errorf("change %v already %s", ch.cuid, state.String()) + continue + } + // reset ticker to enable activate the change timeout + ticker.Reset(timeout) + err := ch.callback(ch.previousState, ch.intendedState) + if err != nil { + ch.stateMu.Lock() + ch.state = ppb.Change_INCONSISTENT + ch.stateMu.Unlock() + errChan <- err + continue + } + ch.stateMu.Lock() + ch.state = ppb.Change_COMMITTED + ch.stateMu.Unlock() + stateOut <- state + case ppb.Change_CONFIRMED: + state := ch.State() + if state != ppb.Change_COMMITTED { + errChan <- fmt.Errorf("cannot confirm uncommitted change %v", ch.cuid) + continue + } + // The change has been confirmed and the timer is stopped, + // since a rollback is not necessary anymore. + ch.stateMu.Lock() + ch.state = ppb.Change_CONFIRMED + ch.stateMu.Unlock() + stateOut <- state + ch.stateManagerCancel() + } + case <-ctx.Done(): + ticker.Stop() + break running + } + } + log.Info("statemanager routine done for: ", ch.cuid) + }() + return stateIn, stateOut, errChan +} diff --git a/nucleus/change_test.go b/nucleus/change_test.go new file mode 100644 index 0000000000000000000000000000000000000000..bb59c2f97706ad7522c40e51e601c0fed576c6fd --- /dev/null +++ b/nucleus/change_test.go @@ -0,0 +1,305 @@ +package nucleus + +import ( + "context" + "errors" + "reflect" + "sync" + "testing" + "time" + + ppb "code.fbi.h-da.de/danet/api/go/gosdn/pnd" + "code.fbi.h-da.de/danet/gosdn/config" + "github.com/google/uuid" + "github.com/openconfig/ygot/exampleoc" + "github.com/openconfig/ygot/ygot" +) + +var commitHostname = "commit" +var rollbackHostname = "rollback" + +var commitDevice = &exampleoc.Device{ + System: &exampleoc.System{ + Hostname: &commitHostname, + }, +} + +var rollbackDevice = &exampleoc.Device{ + System: &exampleoc.System{ + Hostname: &rollbackHostname, + }, +} + +func TestChange_CommitRollback(t *testing.T) { + wg := sync.WaitGroup{} + wantErr := false + want := rollbackHostname + callback := make(chan string) + c := &Change{ + cuid: cuid, + duid: did, + timestamp: time.Now(), + previousState: rollbackDevice, + intendedState: commitDevice, + callback: func(first ygot.GoStruct, second ygot.GoStruct) error { + hostname := *first.(*exampleoc.Device).System.Hostname + t.Logf("callback in test %v", t.Name()) + switch hostname { + case rollbackHostname: + callback <- rollbackHostname + } + return nil + }, + } + stateManagerCtx, stateManagerCancel := context.WithCancel(context.Background()) + stateIn, stateOut, errChan := stateManager(stateManagerCtx, c, time.Millisecond*100) + c.stateIn = stateIn + c.stateOut = stateOut + c.errChan = errChan + c.stateManagerCancel = stateManagerCancel + wg.Add(1) + go func() { + defer wg.Done() + time.Sleep(time.Millisecond * 10) + if err := c.Commit(); (err != nil) != wantErr { + t.Errorf("Commit() error = %v, wantErr %v", err, wantErr) + } + time.Sleep(config.ChangeTimeout) + }() + got := <-callback + if !reflect.DeepEqual(got, want) { + t.Errorf("Commit() = %v, want %v", got, want) + } + wg.Wait() + c.stateManagerCancel() +} + +func TestChange_CommitRollbackError(t *testing.T) { + wg := sync.WaitGroup{} + wg.Add(1) + wantErr := false + want := errors.New("this is an expected error") + rollbackErrChannel := make(chan error) + c := &Change{ + cuid: cuid, + duid: did, + timestamp: time.Now(), + previousState: rollbackDevice, + intendedState: commitDevice, + callback: func(first ygot.GoStruct, second ygot.GoStruct) error { + hostname := *second.(*exampleoc.Device).System.Hostname + t.Logf("callback in test %v", t.Name()) + switch hostname { + case rollbackHostname: + rollbackErrChannel <- errors.New("this is an expected error") + } + return nil + }, + } + stateManagerCtx, stateManagerCancel := context.WithCancel(context.Background()) + stateIn, stateOut, errChan := stateManager(stateManagerCtx, c, time.Millisecond*100) + c.stateIn = stateIn + c.stateOut = stateOut + c.errChan = errChan + c.stateManagerCancel = stateManagerCancel + + go func() { + defer wg.Done() + time.Sleep(time.Millisecond * 10) + if err := c.Commit(); (err != nil) != wantErr { + t.Errorf("Commit() error = %v, wantErr %v", err, wantErr) + } + time.Sleep(config.ChangeTimeout) + }() + got := <-rollbackErrChannel + if !reflect.DeepEqual(got, want) { + t.Errorf("Commit() = %v, want %v", got, want) + } + wg.Wait() + c.stateManagerCancel() +} + +func TestChange_CommitError(t *testing.T) { + want := ppb.Change_INCONSISTENT + c := &Change{ + cuid: cuid, + duid: did, + timestamp: time.Now(), + previousState: rollbackDevice, + intendedState: commitDevice, + callback: func(first ygot.GoStruct, second ygot.GoStruct) error { + return errors.New("this is an expected error") + }, + } + stateManagerCtx, stateManagerCancel := context.WithCancel(context.Background()) + stateIn, stateOut, errChan := stateManager(stateManagerCtx, c, time.Millisecond*100) + c.stateIn = stateIn + c.stateOut = stateOut + c.errChan = errChan + c.stateManagerCancel = stateManagerCancel + + time.Sleep(time.Millisecond * 10) + if err := c.Commit(); err == nil { + t.Errorf("Commit() expected error, error = %v", err) + } + got := c.State() + if !reflect.DeepEqual(got, want) { + t.Errorf("Commit() = %v, want %v", got, want) + } + c.stateManagerCancel() +} + +func TestChange_Commit(t *testing.T) { + want := ppb.Change_COMMITTED + c := &Change{ + cuid: cuid, + duid: did, + timestamp: time.Now(), + previousState: rollbackDevice, + intendedState: commitDevice, + callback: func(first ygot.GoStruct, second ygot.GoStruct) error { + t.Logf("callback in test %v", t.Name()) + return nil + }, + } + stateManagerCtx, stateManagerCancel := context.WithCancel(context.Background()) + stateIn, stateOut, errChan := stateManager(stateManagerCtx, c, time.Millisecond*100) + c.stateIn = stateIn + c.stateOut = stateOut + c.errChan = errChan + c.stateManagerCancel = stateManagerCancel + + if err := c.Commit(); err != nil { + t.Errorf("Commit() error = %v", err) + } + got := c.State() + if !reflect.DeepEqual(got, want) { + t.Errorf("Commit() = %v, want %v", got, want) + } + if err := c.Confirm(); err != nil { + t.Errorf("Confirm() error = %v", err) + } +} + +func TestChange_Confirm(t *testing.T) { + tests := []struct { + name string + wantErr bool + }{ + { + name: "committed", + wantErr: false, + }, + { + name: "uncommitted", + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := &Change{ + previousState: &exampleoc.Device{ + System: &exampleoc.System{ + Hostname: &rollbackHostname, + }, + }, + intendedState: &exampleoc.Device{ + System: &exampleoc.System{ + Hostname: &commitHostname, + }, + }, + callback: func(first ygot.GoStruct, second ygot.GoStruct) error { + t.Logf("callback in test %v", t.Name()) + return nil + }, + } + stateManagerCtx, stateManagerCancel := context.WithCancel(context.Background()) + stateIn, stateOut, errChan := stateManager(stateManagerCtx, c, time.Millisecond*100) + c.stateIn = stateIn + c.stateOut = stateOut + c.errChan = errChan + c.stateManagerCancel = stateManagerCancel + + if tt.name == "committed" { + if err := c.Commit(); err != nil { + t.Errorf("Commit() error = %v, wantErr %v", err, tt.wantErr) + } + } + if err := c.Confirm(); (err != nil) != tt.wantErr { + t.Errorf("Confirm() error = %v, wantErr %v", err, tt.wantErr) + } + c.stateManagerCancel() + }) + } +} + +func TestChange_ID(t *testing.T) { + type fields struct { + cuid uuid.UUID + } + tests := []struct { + name string + fields fields + want uuid.UUID + }{ + { + name: "default", + fields: fields{cuid: cuid}, + want: cuid, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := &Change{ + cuid: tt.fields.cuid, + } + if got := c.ID(); !reflect.DeepEqual(got, tt.want) { + t.Errorf("ID() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestChange_State(t *testing.T) { + tests := []struct { + name string + want ppb.Change_State + }{ + { + name: "pending", + want: ppb.Change_PENDING, + }, + { + name: "committed", + want: ppb.Change_COMMITTED, + }, + { + name: "confirmed", + want: ppb.Change_CONFIRMED, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + testName := t.Name() + callback := func(first ygot.GoStruct, second ygot.GoStruct) error { + t.Logf("callback in test %v", testName) + return nil + } + c := NewChange(did, rollbackDevice, commitDevice, callback) + if tt.name != "pending" { + if err := c.Commit(); err != nil { + t.Errorf("Commit() error = %v", err) + } + } + if tt.name == "confirmed" { + if err := c.Confirm(); err != nil { + t.Errorf("Confirm() error = %v", err) + } + } + if got := c.State(); !reflect.DeepEqual(got, tt.want) { + t.Errorf("Change.State() = %v, want %v", got, tt.want) + } + c.stateManagerCancel() + }) + } +} diff --git a/nucleus/controller.go b/nucleus/controller.go deleted file mode 100644 index 4e96a290b394a596dd2568b73305f1f7a27f7dc8..0000000000000000000000000000000000000000 --- a/nucleus/controller.go +++ /dev/null @@ -1,105 +0,0 @@ -package nucleus - -import ( - "code.fbi.h-da.de/cocsn/gosdn/database" - "context" - "github.com/google/uuid" - log "github.com/sirupsen/logrus" - "net/http" - "os" - "os/signal" - "sync" - "time" -) - -var coreLock sync.RWMutex -var coreOnce sync.Once - -// Core is the representation of the controllers core -type Core struct { - // deprecated - database database.Database - - pndc pndStore - sbic sbiStore - httpServer *http.Server - stopChan chan os.Signal -} - -var c *Core - -func init() { - c = &Core{ - database: database.Database{}, - pndc: pndStore{store{}}, - sbic: sbiStore{store{}}, - stopChan: make(chan os.Signal, 1), - } - - // Setting up signal capturing - signal.Notify(c.stopChan, os.Interrupt) -} - -// initialize does start-up housekeeping like reading controller config files -func initialize() error { - if err := createSouthboundInterfaces(); err != nil { - return err - } - - // TODO: Start grpc listener here - coreLock.Lock() - defer coreLock.Unlock() - return httpAPI() -} - -// createSouthboundInterfaces initializes the controller with its supported SBIs -func createSouthboundInterfaces() error { - sbi := &OpenConfig{id: uuid.New()} - if err := c.sbic.add(sbi); err != nil { - return err - } - return createPrincipalNetworkDomain(sbi) -} - -// createPrincipalNetworkDomain initializes the controller with an initial PND -func createPrincipalNetworkDomain(sbi SouthboundInterface) error { - pnd, err := NewPND("base", "gosdn base pnd", uuid.New(), sbi) - if err != nil { - return err - } - err = c.pndc.add(pnd) - if err != nil { - return err - } - return nil -} - -// Run calls initialize to start the controller -func Run(ctx context.Context) error { - var initError error - coreOnce.Do(func() { - initError = initialize() - }) - if initError != nil { - log.WithFields(log.Fields{}).Error(initError) - return initError - } - log.WithFields(log.Fields{}).Info("initialisation finished") - for { - select { - case <-c.stopChan: - return shutdown() - case <-ctx.Done(): - return shutdown() - case <-time.Tick(time.Minute): - log.Debug("up and running") - } - } -} - -func shutdown() error { - log.Info("shutting down controller") - coreLock.Lock() - defer coreLock.Unlock() - return stopHttpServer() -} diff --git a/nucleus/device.go b/nucleus/device.go index 4318f72420a10e61aa36f1bc7680452e0f640ff9..80034d540f187469b60347967f10de3fead546d4 100644 --- a/nucleus/device.go +++ b/nucleus/device.go @@ -1,49 +1,213 @@ package nucleus import ( + "encoding/json" + + spb "code.fbi.h-da.de/danet/api/go/gosdn/southbound" + tpb "code.fbi.h-da.de/danet/api/go/gosdn/transport" + "code.fbi.h-da.de/danet/gosdn/interfaces/device" + "code.fbi.h-da.de/danet/gosdn/interfaces/southbound" + "code.fbi.h-da.de/danet/gosdn/interfaces/transport" + "github.com/docker/docker/pkg/namesgenerator" "github.com/google/uuid" "github.com/openconfig/ygot/ygot" + "google.golang.org/protobuf/proto" ) -// Device represents an Orchestrated Network Device (OND) which is managed by -// nucleus -type Device struct { +// NewDevice creates a Device +func NewDevice(name string, uuidInput uuid.UUID, opt *tpb.TransportOption, sbi southbound.SouthboundInterface) (device.Device, error) { + t, err := NewTransport(opt, sbi) + if err != nil { + return nil, err + } + + // TODO: this needs to check the case that the uuidInput is set, as the same uuid may be already stored. + if uuidInput == uuid.Nil { + uuidInput = uuid.New() + } + + if name == "" { + name = namesgenerator.GetRandomName(0) + } + + root, err := ygot.DeepCopy(sbi.Schema().Root) + if err != nil { + return nil, err + } + if opt.Type == spb.Type_CONTAINERISED { + return &CsbiDevice{ + CommonDevice: CommonDevice{ + UUID: uuidInput, + GoStruct: root, + sbi: sbi, + transport: t, + name: name, + transportOptions: opt, + }, + }, nil + } + + return &CommonDevice{ + UUID: uuidInput, + GoStruct: root, + sbi: sbi, + transport: t, + name: name, + transportOptions: opt, + }, nil +} + +// CommonDevice represents an OND +type CommonDevice struct { // UUID represents the Devices UUID UUID uuid.UUID - // Device inherits properties of ygot.GoStruct + // Device embeds a ygot.GoStruct containing the device details ygot.GoStruct // SBI is the device's southbound interface implementation - SBI SouthboundInterface + sbi southbound.SouthboundInterface // Transport is the device's Transport implementation - Transport Transport + transport transport.Transport + + // Name is the device's human readable name + name string + + transportOptions *tpb.TransportOption } -// NewDevice creates a Device -func NewDevice(sbi SouthboundInterface, opts TransportOptions) (*Device, error) { - var transport Transport - var err error - switch opts.(type) { - case *GnmiTransportOptions: - transport, err = NewGnmiTransport(opts.(*GnmiTransportOptions)) - if err != nil { - return nil, err - } - default: - return nil, &ErrInvalidTransportOptions{opts} +// ID returns the UUID of the Device +func (d *CommonDevice) ID() uuid.UUID { + return d.UUID +} - } - return &Device{ - UUID: uuid.New(), - GoStruct: sbi.Schema().Root, - SBI: sbi, - Transport: transport, - }, nil +// Model returns the ygot representation of the Device +func (d *CommonDevice) Model() ygot.GoStruct { + return d.GoStruct +} + +// Transport returns the Transport of the device +func (d *CommonDevice) Transport() transport.Transport { + return d.transport +} + +// Name returns the name of the device +func (d *CommonDevice) Name() string { + return d.name +} + +// SBI returns the sbi of the Device +func (d *CommonDevice) SBI() southbound.SouthboundInterface { + return d.sbi +} + +// SetTransport sets the Device's Transport +func (d *CommonDevice) SetTransport(t transport.Transport) { + d.transport = t +} + +// SetName sets the Device's name +func (d *CommonDevice) SetName(n string) { + d.name = n +} + +// SetSBI sets the Device's SBI +func (d *CommonDevice) SetSBI(sbi southbound.SouthboundInterface) { + d.sbi = sbi +} + +// ProcessResponse processes a response for the Device +func (d *CommonDevice) ProcessResponse(resp proto.Message) error { + return d.transport.ProcessResponse(resp, d.GoStruct, d.sbi.Schema()) +} + +// CsbiDevice is used for the cSBI functionality. +type CsbiDevice struct { + CommonDevice } // ID returns the UUID of the Device -func (d *Device) ID() uuid.UUID { +func (d *CsbiDevice) ID() uuid.UUID { return d.UUID } + +// Model returns the ygot representation of the Device +func (d *CsbiDevice) Model() ygot.GoStruct { + return d.GoStruct +} + +// Transport returns the Transport of the device +func (d *CsbiDevice) Transport() transport.Transport { + return d.transport +} + +// Name returns the name of the device +func (d *CsbiDevice) Name() string { + return d.name +} + +// SBI returns the sbi of the Device +func (d *CsbiDevice) SBI() southbound.SouthboundInterface { + return d.sbi +} + +// ProcessResponse processes a response for the Device +func (d *CsbiDevice) ProcessResponse(resp proto.Message) error { + // TODO: callback to send response to caller + return d.transport.ProcessResponse(resp, d.GoStruct, d.sbi.Schema()) +} + +// MarshalJSON implements the MarshalJSON interface to store a device as JSON +func (d *CommonDevice) MarshalJSON() ([]byte, error) { + var transportType string + var transportAddress string + var transportUsername string + var transportPassword string + var transportOptionType spb.Type + + // Handling of these cases is necessary as we use partial devices for testing. + // eg. in most tests no transport or sbi is defined. + // The marshaller will crash if we want to access a nil field. + if d.transport == nil || d.transportOptions == nil { + transportType = "testing" + transportAddress = "testing" + transportUsername = "testing" + transportPassword = "testing" + transportOptionType = spb.Type_OPENCONFIG + } else { + transportType = d.transport.Type() + transportAddress = d.transportOptions.Address + transportUsername = d.transportOptions.Username + transportPassword = d.transportOptions.Password + transportOptionType = d.transportOptions.Type + } + + var sbiUUID uuid.UUID + + if d.sbi == nil { + sbiUUID = uuid.UUID{} + } else { + sbiUUID = d.sbi.ID() + } + + return json.Marshal(&struct { + DeviceID uuid.UUID `json:"id,omitempty"` + Name string `json:"name,omitempty"` + TransportType string `json:"transport_type,omitempty"` + TransportAddress string `json:"transport_address,omitempty"` + TransportUsername string `json:"transport_username,omitempty"` + TransportPassword string `json:"transport_password,omitempty"` + TransportOptionType spb.Type `json:"transport_option"` + SBI uuid.UUID `json:"sbi,omitempty"` + }{ + DeviceID: d.ID(), + Name: d.Name(), + TransportType: transportType, + TransportAddress: transportAddress, + TransportUsername: transportUsername, + TransportPassword: transportPassword, + TransportOptionType: transportOptionType, + SBI: sbiUUID, + }) +} diff --git a/nucleus/device_test.go b/nucleus/device_test.go index 0c6f118ccf4cbdff858f96003e6cf1dff86bc375..7b6a5e84388b8474ca2a3ad119d48679c1c72306 100644 --- a/nucleus/device_test.go +++ b/nucleus/device_test.go @@ -1,20 +1,26 @@ package nucleus import ( - "code.fbi.h-da.de/cocsn/gosdn/forks/goarista/gnmi" - "code.fbi.h-da.de/cocsn/yang-models/generated/openconfig" - "github.com/google/uuid" - "github.com/openconfig/ygot/ygot" "reflect" "testing" + + "code.fbi.h-da.de/danet/gosdn/interfaces/southbound" + "code.fbi.h-da.de/danet/gosdn/interfaces/transport" + + tpb "code.fbi.h-da.de/danet/api/go/gosdn/transport" + + "code.fbi.h-da.de/danet/yang-models/generated/openconfig" + "github.com/google/uuid" + "github.com/openconfig/ygot/ygot" ) func TestDevice_Id(t *testing.T) { type fields struct { GoStruct ygot.GoStruct - SBI SouthboundInterface - Transport Transport + SBI southbound.SouthboundInterface + Transport transport.Transport UUID uuid.UUID + Name string } tests := []struct { name string @@ -31,11 +37,12 @@ func TestDevice_Id(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - d := &Device{ + d := &CommonDevice{ GoStruct: tt.fields.GoStruct, - SBI: tt.fields.SBI, - Transport: tt.fields.Transport, + sbi: tt.fields.SBI, + transport: tt.fields.Transport, UUID: tt.fields.UUID, + name: tt.fields.Name, } if got := d.ID(); !reflect.DeepEqual(got, tt.want) { t.Errorf("ID() = %v, want %v", got, tt.want) @@ -47,57 +54,69 @@ func TestDevice_Id(t *testing.T) { func TestNewDevice(t *testing.T) { sbi := &OpenConfig{} type args struct { - sbi SouthboundInterface - opts TransportOptions + sbi southbound.SouthboundInterface + opts *tpb.TransportOption + name string } tests := []struct { name string args args - want *Device wantErr bool }{ { name: "default", args: args{ sbi: sbi, - opts: &GnmiTransportOptions{ - Config: gnmi.Config{ - Addr: "test:///", - Username: "test", - Password: "test", + opts: &tpb.TransportOption{ + Address: "test:///", + Username: "test", + Password: "test", + TransportOption: &tpb.TransportOption_GnmiTransportOption{ + GnmiTransportOption: &tpb.GnmiTransportOption{ + Compression: "", + GrpcDialOptions: nil, + Token: "", + Encoding: 0, + }, }, }, + name: "MyDevice", }, - want: &Device{ - GoStruct: &openconfig.Device{}, - SBI: sbi, - UUID: uuid.New(), - Transport: &Gnmi{ - Options: &GnmiTransportOptions{ - Config: gnmi.Config{ - Addr: "test:///", - Username: "test", - Password: "test", - }, - }, + }, + { + name: "invalid options", + args: args{ + sbi: sbi, + opts: &tpb.TransportOption{ + Address: "test:///", + Username: "test", + Password: "test", }, + name: "MyDevice", }, + wantErr: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := NewDevice(tt.args.sbi, tt.args.opts) - if err != nil { - t.Error(err) - } - tt.want.Transport.(*Gnmi).client = got.Transport.(*Gnmi).client - tt.want.UUID = got.ID() + resp, err := NewDevice(tt.args.name, uuid.Nil, tt.args.opts, tt.args.sbi) if (err != nil) != tt.wantErr { t.Errorf("NewDevice() error = %v, wantErr %v", err, tt.wantErr) return } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("NewDevice() got = %v, want %v", got, tt.want) + if resp != nil { + if reflect.TypeOf(resp.Model()) != reflect.TypeOf(&openconfig.Device{}) { + t.Error("NewDevice() returned invalid GoStruct") + } + if reflect.TypeOf(resp.Transport()) != reflect.TypeOf(&Gnmi{}) { + t.Error("NewDevice() returned invalid transport") + } + if reflect.TypeOf(resp.SBI()) != reflect.TypeOf(&OpenConfig{}) { + t.Error("NewDevice() returned invalid GoStruct") + } + if resp.Name() != "MyDevice" { + t.Error("NewDevice() returned wrong name") + } } }) } diff --git a/nucleus/errors.go b/nucleus/errors/errors.go similarity index 65% rename from nucleus/errors.go rename to nucleus/errors/errors.go index 8bd01fe67150cba93b9c6f2cb5710ae63383b11c..43bce0f1d71ae60e66d9f0288e1c4ad21632f42b 100644 --- a/nucleus/errors.go +++ b/nucleus/errors/errors.go @@ -1,4 +1,4 @@ -package nucleus +package errors import ( "fmt" @@ -24,42 +24,51 @@ func (e *ErrNil) Error() string { // ErrNotFound implements the Error interface and is called if a specific ID // of a storable item could not be found. type ErrNotFound struct { - id interface{} + ID interface{} } func (e *ErrNotFound) Error() string { - return fmt.Sprintf("%v not found", e.id) + return fmt.Sprintf("%v not found", e.ID) } // ErrAlreadyExists implements the Error interface and is called if a specific ID // of a storable item already exists. type ErrAlreadyExists struct { - item interface{} + Item interface{} } func (e *ErrAlreadyExists) Error() string { - return fmt.Sprintf("%v already exists", e.item) + return fmt.Sprintf("%T %v already exists", e.Item, e.Item) +} + +// ErrInvalidUUID implements the Error interface and is called if a UUID is not valid. +type ErrInvalidUUID struct { + DeviceName string +} + +func (e *ErrInvalidUUID) Error() string { + return fmt.Sprintf("UUID not valid") } // ErrInvalidTypeAssertion implements the Error interface and is called if the // type of a storable item does not correspond to the expected type. type ErrInvalidTypeAssertion struct { - v interface{} - t interface{} + Value interface{} + Type interface{} } func (e ErrInvalidTypeAssertion) Error() string { - return fmt.Sprintf("%v does not implement %v", e.v, e.t) + return fmt.Sprintf("%v does not implement %v", reflect.TypeOf(e.Value).Elem(), reflect.TypeOf(e.Type).Elem()) } // ErrUnsupportedPath implements the Error interface and is called if the // given path is not supported. type ErrUnsupportedPath struct { - p interface{} + Path interface{} } func (e ErrUnsupportedPath) Error() string { - return fmt.Sprintf("path %v is not supported", e.p) + return fmt.Sprintf("path %v is not supported", e.Path) } // ErrNotYetImplemented implements the Error interface and is called if a function @@ -73,20 +82,30 @@ func (e ErrNotYetImplemented) Error() string { // ErrInvalidParameters implements the Error interface and is called if the wrong // or no parameters have been provided. type ErrInvalidParameters struct { - f interface{} - r interface{} + Func interface{} + Param interface{} } func (e ErrInvalidParameters) Error() string { - return fmt.Sprintf("invalid parameters for %v: %v", e.f, e.r) + return fmt.Sprintf("invalid parameters for %v: %v", e.Func, e.Param) } // ErrInvalidTransportOptions implements the Error interface and is called if the // wrong TransportOptions have been provided. type ErrInvalidTransportOptions struct { - t interface{} + Opt interface{} } func (e ErrInvalidTransportOptions) Error() string { - return fmt.Sprintf("invalid transport options: %v", reflect.TypeOf(e.t)) + return fmt.Sprintf("invalid transport options: %v", reflect.TypeOf(e.Opt)) +} + +// ErrOperationNotSupported implements the Error interface and is called if the +// wrong Operation has been provided. +type ErrOperationNotSupported struct { + Op interface{} +} + +func (e ErrOperationNotSupported) Error() string { + return fmt.Sprintf("transport operation not supported: %v", reflect.TypeOf(e.Op)) } diff --git a/nucleus/gnmi_transport.go b/nucleus/gnmi_transport.go index 3bbcc03c6146804d862af1932f5cac2a4a0fca86..37f6f772680f4de808f51b75c663fc14040e99b0 100644 --- a/nucleus/gnmi_transport.go +++ b/nucleus/gnmi_transport.go @@ -1,27 +1,25 @@ package nucleus import ( - "code.fbi.h-da.de/cocsn/gosdn/forks/goarista/gnmi" "context" + "fmt" + + "code.fbi.h-da.de/danet/gosdn/interfaces/change" + + "code.fbi.h-da.de/danet/gosdn/interfaces/southbound" + + ppb "code.fbi.h-da.de/danet/api/go/gosdn/pnd" + + "code.fbi.h-da.de/danet/forks/goarista/gnmi" + "code.fbi.h-da.de/danet/gosdn/nucleus/errors" + "code.fbi.h-da.de/danet/gosdn/nucleus/types" gpb "github.com/openconfig/gnmi/proto/gnmi" - "github.com/openconfig/gnmi/proto/gnmi_ext" "github.com/openconfig/goyang/pkg/yang" + "github.com/openconfig/ygot/ygot" "github.com/openconfig/ygot/ytypes" log "github.com/sirupsen/logrus" - "reflect" - "strings" -) - -// CtxKeyType is a custom type to be used as key in a context.WithValue() or -// context.Value() call. For more information see: -// https://www.calhoun.io/pitfalls-of-context-values-and-how-to-avoid-or-mitigate-them/ -type CtxKeyType string -const ( - // CtxKeyOpts context key for gnmi.SubscribeOptions - CtxKeyOpts CtxKeyType = "opts" - // CtxKeyConfig is a context key for gnmi.Config - CtxKeyConfig = "config" + tpb "code.fbi.h-da.de/danet/api/go/gosdn/transport" ) // Gnmi implements the Transport interface and provides an SBI with the @@ -29,97 +27,100 @@ const ( type Gnmi struct { SetNode func(schema *yang.Entry, root interface{}, path *gpb.Path, val interface{}, opts ...ytypes.SetNodeOpt) error RespChan chan *gpb.SubscribeResponse - Unmarshal func([]byte, []string, interface{}, ...ytypes.UnmarshalOpt) error - Options *GnmiTransportOptions + Unmarshal func([]byte, *gpb.Path, ygot.ValidatedGoStruct, ...ytypes.UnmarshalOpt) error + Options *tpb.TransportOption client gpb.GNMIClient + config *gnmi.Config } -// NewGnmiTransport takes a struct of GnmiTransportOptions and returns a Gnmi +// newGnmiTransport takes a struct of GnmiTransportOptions and returns a Gnmi // transport based on the values of it. -func NewGnmiTransport(opts *GnmiTransportOptions) (*Gnmi, error) { - c, err := gnmi.Dial(&opts.Config) +// Do not call directly. Use NewTransport() instead. +func newGnmiTransport(opts *tpb.TransportOption, sbi southbound.SouthboundInterface) (*Gnmi, error) { + if opts == nil || sbi == nil { + return nil, &errors.ErrInvalidParameters{ + Func: newGnmiTransport, + Param: "'opts' and 'sbi' can not be nil", + } + } else if opts.TransportOption == nil { + return nil, &errors.ErrInvalidParameters{ + Func: newGnmiTransport, + Param: "'opts.TransportOption' can not be nil", + } + } + gnmiConfig := &gnmi.Config{ + Addr: opts.Address, + Password: opts.Password, + Username: opts.Username, + TLS: opts.Tls, + Compression: opts.GetGnmiTransportOption().GetCompression(), + } + c, err := gnmi.Dial(gnmiConfig) if err != nil { return nil, err } log.WithFields(log.Fields{ - "target": opts.Addr, - "tls": opts.TLS, - "encoding": opts.Encoding, + "target": opts.Address, + "tls": opts.Tls, }).Info("building new gNMI transport") return &Gnmi{ - SetNode: opts.SetNode, - RespChan: opts.RespChan, - Options: opts, - client: c, + SetNode: sbi.SetNode, + RespChan: make(chan *gpb.SubscribeResponse), + Unmarshal: sbi.Unmarshal, + Options: opts, + client: c, + config: gnmiConfig, }, nil } -//SetOptions sets Gnmi Options -func (g *Gnmi) SetOptions(to TransportOptions) { - g.Options = to.(*GnmiTransportOptions) -} - -//GetOptions returns the Gnmi options -func (g *Gnmi) GetOptions() interface{} { - return g.Options -} - // Get takes a slice of gnmi paths, splits them and calls get for each one of them. func (g *Gnmi) Get(ctx context.Context, params ...string) (interface{}, error) { if g.client == nil { - return nil, &ErrNilClient{} + return nil, &errors.ErrNilClient{} } + ctx = gnmi.NewContext(ctx, g.config) paths := gnmi.SplitPaths(params) return g.get(ctx, paths, "") } -// Set takes a slice of params. This slice must contain at least one operation. -// It can contain an additional arbitrary amount of operations and extensions. -func (g *Gnmi) Set(ctx context.Context, args ...interface{}) (interface{}, error) { +// Set takes a change.Payload struct. +func (g *Gnmi) Set(ctx context.Context, payload change.Payload) error { if g.client == nil { - return nil, &ErrNilClient{} - } - if len(args) == 0 { - return nil, &ErrInvalidParameters{ - f: "gnmi.Set()", - r: "no parameters provided", - } + return &errors.ErrNilClient{} } + ctx = gnmi.NewContext(ctx, g.config) + return g.applyDiff(ctx, payload) +} - // Loop over args and create ops and exts - // Invalid args cause unhealable error - ops := make([]*gnmi.Operation, 0) - exts := make([]*gnmi_ext.Extension, 0) - for _, p := range args { - switch p.(type) { - case *gnmi.Operation: - op := p.(*gnmi.Operation) - if op.Target == "" { - op.Target = g.Options.Addr - } - ops = append(ops, op) - case *gnmi_ext.Extension: - exts = append(exts, p.(*gnmi_ext.Extension)) - default: - return nil, &ErrInvalidParameters{ - f: "gnmi.Set()", - r: "args contain invalid type", - } - } +func (g *Gnmi) applyDiff(ctx context.Context, payload change.Payload) error { + op := ctx.Value(types.CtxKeyOperation) + + diff, err := ygot.Diff(payload.Original, payload.Modified) + if err != nil { + return err } - if len(ops) == 0 { - return nil, &ErrInvalidParameters{ - f: "gnmi.Set()", - r: "no operations provided", + req := &gpb.SetRequest{} + if diff.Update != nil { + switch op { + case ppb.ApiOperation_UPDATE: + req.Update = diff.Update + case ppb.ApiOperation_REPLACE: + req.Replace = diff.Update + default: + return &errors.ErrOperationNotSupported{Op: op} } + } else if diff.Delete != nil { + req.Delete = diff.Delete } - return g.set(ctx, ops, exts...) + resp, err := g.client.Set(ctx, req) + log.Info(resp) + return err } //Subscribe subscribes to a gNMI target func (g *Gnmi) Subscribe(ctx context.Context, params ...string) error { if g.client == nil { - return &ErrNilClient{} + return &errors.ErrNilClient{} } return g.subscribe(ctx) } @@ -129,49 +130,65 @@ func (g *Gnmi) Type() string { return "gnmi" } -// ProcessResponse takes a gNMI response and serializes the contents to the root struct. +// ProcessResponse takes a gNMI response and serializes the contents to the +// root struct. It logs all errors and returns an error containing the number +// off errors encountered during the process. func (g *Gnmi) ProcessResponse(resp interface{}, root interface{}, s *ytypes.Schema) error { - models := s.SchemaTree - r := resp.(*gpb.GetResponse) + d, ok := root.(ygot.ValidatedGoStruct) + if !ok { + return &errors.ErrInvalidTypeAssertion{ + Value: root, + Type: (*ygot.ValidatedGoStruct)(nil), + } + } + r, ok := resp.(*gpb.GetResponse) + if !ok { + return &errors.ErrInvalidTypeAssertion{ + Value: resp, + Type: &gpb.GetResponse{}, + } + } rn := r.Notification + errs := make([]error, 0) for _, msg := range rn { for _, update := range msg.Update { path := update.Path - fullPath := path - val, ok := update.Val.Value.(*gpb.TypedValue_JsonIetfVal) - if ok { + switch val := update.Val.Value.(type) { + case *gpb.TypedValue_JsonVal: opts := []ytypes.UnmarshalOpt{&ytypes.IgnoreExtraFields{}} - if err := g.Unmarshal(val.JsonIetfVal, extraxtPathElements(fullPath), root, opts...); err != nil { - return err + if err := g.Unmarshal(val.JsonVal, path, d, opts...); err != nil { + errs = append(errs, err) + } + case *gpb.TypedValue_JsonIetfVal: + opts := []ytypes.UnmarshalOpt{&ytypes.IgnoreExtraFields{}} + if err := g.Unmarshal(val.JsonIetfVal, path, d, opts...); err != nil { + errs = append(errs, err) + } + default: + schema := s.RootSchema() + opts := []ytypes.SetNodeOpt{&ytypes.InitMissingElements{}, &ytypes.TolerateJSONInconsistencies{}} + if err := g.SetNode(schema, root, update.Path, update.Val, opts...); err != nil { + errs = append(errs, err) } - return nil - } - // TODO(mk): Evaluate hardcoded model key - schema := models["Device"] - opts := []ytypes.SetNodeOpt{&ytypes.InitMissingElements{}, &ytypes.TolerateJSONInconsistencies{}} - if err := g.SetNode(schema, root, update.Path, update.Val, opts...); err != nil { - return err } } } - return nil -} - -func extraxtPathElements(path *gpb.Path) []string { - elems := make([]string, len(path.Elem)) - for i, e := range path.Elem { - elems[i] = strings.Title(e.Name) + for _, e := range errs { + log.Error(e) + } + if len(errs) != 0 { + return fmt.Errorf("encountered %v errors during response processing\n%v", len(errs), errs) } - return elems + return nil } // Capabilities calls GNMI capabilities func (g *Gnmi) Capabilities(ctx context.Context) (interface{}, error) { log.WithFields(log.Fields{ - "target": g.Options.Addr, + "target": g.Options.Address, }).Info("sending gNMI capabilities request") - ctx = gnmi.NewContext(ctx, &g.Options.Config) - ctx = context.WithValue(ctx, CtxKeyConfig, &g.Options.Config) //nolint + ctx = gnmi.NewContext(ctx, g.config) + ctx = context.WithValue(ctx, types.CtxKeyConfig, g.config) //nolint resp, err := g.client.Capabilities(ctx, &gpb.CapabilityRequest{}) if err != nil { return nil, err @@ -181,9 +198,7 @@ func (g *Gnmi) Capabilities(ctx context.Context) (interface{}, error) { // get calls GNMI get func (g *Gnmi) get(ctx context.Context, paths [][]string, origin string) (interface{}, error) { - - ctx = gnmi.NewContext(ctx, &g.Options.Config) - ctx = context.WithValue(ctx, CtxKeyConfig, &g.Options.Config) //nolint + ctx = context.WithValue(ctx, types.CtxKeyConfig, g.config) //nolint req, err := gnmi.NewGetRequest(ctx, paths, origin) if err != nil { return nil, err @@ -195,10 +210,10 @@ func (g *Gnmi) get(ctx context.Context, paths [][]string, origin string) (interf // and returns any response. func (g *Gnmi) getWithRequest(ctx context.Context, req *gpb.GetRequest) (interface{}, error) { if req == nil { - return nil, &ErrNil{} + return nil, &errors.ErrNil{} } log.WithFields(log.Fields{ - "target": g.Options.Addr, + "target": g.Options.Address, "path": req.Path, }).Info("sending gNMI get request") @@ -209,34 +224,14 @@ func (g *Gnmi) getWithRequest(ctx context.Context, req *gpb.GetRequest) (interfa return resp, nil } -// Set calls GNMI set -func (g *Gnmi) set(ctx context.Context, setOps []*gnmi.Operation, - exts ...*gnmi_ext.Extension) (*gpb.SetResponse, error) { - ctx = gnmi.NewContext(ctx, &g.Options.Config) - targets := make([]string, len(setOps)) - paths := make([][]string, len(setOps)) - values := make([]string, len(setOps)) - for i, v := range setOps { - targets[i] = v.Target - paths[i] = v.Path - values[i] = v.Val - } - log.WithFields(log.Fields{ - "targets": targets, - "paths": paths, - "values": values, - }).Info("sending gNMI set request") - return gnmi.Set(ctx, g.client, setOps, exts...) -} - // Subscribe calls GNMI subscribe func (g *Gnmi) subscribe(ctx context.Context) error { - ctx = gnmi.NewContext(ctx, &g.Options.Config) - opts, ok := ctx.Value(CtxKeyOpts).(*gnmi.SubscribeOptions) + ctx = gnmi.NewContext(ctx, g.config) + opts, ok := ctx.Value(types.CtxKeyOpts).(*gnmi.SubscribeOptions) if !ok { - return &ErrInvalidTypeAssertion{ - v: reflect.TypeOf(ctx.Value(CtxKeyOpts)), - t: reflect.TypeOf(&gnmi.SubscribeOptions{}), + return &errors.ErrInvalidTypeAssertion{ + Value: ctx.Value(types.CtxKeyOpts), + Type: &gnmi.SubscribeOptions{}, } } go func() { @@ -263,37 +258,12 @@ func (g *Gnmi) Close() error { return nil } -// GnmiTransportOptions implements the TransportOptions interface. -// GnmiTransportOptions contains all needed information to setup a Gnmi -// transport and therefore inherits gnmi.Config. -type GnmiTransportOptions struct { - // all needed gnmi transport parameters - gnmi.Config - - SetNode func(schema *yang.Entry, root interface{}, path *gpb.Path, - val interface{}, opts ...ytypes.SetNodeOpt) error - Unmarshal func([]byte, []string, interface{}, ...ytypes.UnmarshalOpt) error - RespChan chan *gpb.SubscribeResponse -} - -// GetAddress returns the address used by the transport to connect to a -// gRPC endpoint. -func (gto *GnmiTransportOptions) GetAddress() string { - return gto.Config.Addr +// SetPassthrough allows to pass an existing SetRequest. Used for cSBI +func (g *Gnmi) SetPassthrough(ctx context.Context, req *gpb.SetRequest) (*gpb.SetResponse, error) { + return g.client.Set(ctx, req) } -// GetUsername returns the username used by the transport to connect to a -// gRPC endpoint. -func (gto *GnmiTransportOptions) GetUsername() string { - return gto.Config.Username +// GetPassthrough allows to pass an existing GetRequest. Used for cSBI +func (g *Gnmi) GetPassthrough(ctx context.Context, req *gpb.GetRequest) (*gpb.GetResponse, error) { + return g.client.Get(ctx, req) } - -// GetPassword returns the password used by the transport to connect to a -// gRPC endpoint. -func (gto *GnmiTransportOptions) GetPassword() string { - return gto.Config.Password -} - -// IsTransportOption is needed to fulfill the requirements of the -// TransportOptions interface. It does not need any further implementation. -func (gto *GnmiTransportOptions) IsTransportOption() {} diff --git a/nucleus/gnmi_transport_test.go b/nucleus/gnmi_transport_test.go index 38270c8da5fe3f31f030c5010de2b980a8d8d127..376f0363209eb0b9856b67511cefc0bf7e5ad18a 100644 --- a/nucleus/gnmi_transport_test.go +++ b/nucleus/gnmi_transport_test.go @@ -1,18 +1,25 @@ package nucleus import ( - "code.fbi.h-da.de/cocsn/gosdn/forks/goarista/gnmi" - "code.fbi.h-da.de/cocsn/gosdn/mocks" - "code.fbi.h-da.de/cocsn/yang-models/generated/openconfig" "context" "errors" + "reflect" + "testing" + + "code.fbi.h-da.de/danet/gosdn/interfaces/change" + + "code.fbi.h-da.de/danet/gosdn/interfaces/southbound" + + spb "code.fbi.h-da.de/danet/api/go/gosdn/southbound" + tpb "code.fbi.h-da.de/danet/api/go/gosdn/transport" + + "code.fbi.h-da.de/danet/forks/goarista/gnmi" + "code.fbi.h-da.de/danet/gosdn/mocks" + "code.fbi.h-da.de/danet/yang-models/generated/openconfig" gpb "github.com/openconfig/gnmi/proto/gnmi" - "github.com/openconfig/gnmi/proto/gnmi_ext" "github.com/openconfig/goyang/pkg/yang" "github.com/openconfig/ygot/ytypes" "github.com/stretchr/testify/mock" - "reflect" - "testing" ) // testSetupGnmi bootstraps tests for gnmi transport @@ -98,7 +105,6 @@ func TestGnmi_Close(t *testing.T) { type fields struct { SetNode func(schema *yang.Entry, root interface{}, path *gpb.Path, val interface{}, opts ...ytypes.SetNodeOpt) error RespChan chan *gpb.SubscribeResponse - config *gnmi.Config } tests := []struct { name string @@ -190,7 +196,7 @@ func TestGnmi_Get(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if tt.args.runEndpoint { - startGnmiTarget <- tt.fields.transport.Options.Addr + startGnmiTarget <- tt.fields.transport.config.Addr } got, err := tt.fields.transport.Get(context.Background(), tt.args.params...) if (err != nil) != tt.wantErr { @@ -209,7 +215,7 @@ func TestGnmi_Get(t *testing.T) { func TestGnmi_ProcessResponse(t *testing.T) { type fields struct { - Sbi SouthboundInterface + Sbi southbound.SouthboundInterface } type args struct { path string @@ -228,7 +234,7 @@ func TestGnmi_ProcessResponse(t *testing.T) { path: "../test/proto/resp-interfaces-interface-arista-ceos", root: &openconfig.Device{}, }, - wantErr: true, + wantErr: false, }, { name: "Interfaces Wildcard", @@ -252,8 +258,8 @@ func TestGnmi_ProcessResponse(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { g := &Gnmi{ - SetNode: tt.fields.Sbi.SetNode(), - Unmarshal: tt.fields.Sbi.(*OpenConfig).Unmarshal(), + SetNode: tt.fields.Sbi.SetNode, + Unmarshal: tt.fields.Sbi.(*OpenConfig).Unmarshal, } s := tt.fields.Sbi.Schema() resp := gnmiMessages[tt.args.path] @@ -269,36 +275,29 @@ func TestGnmi_Set(t *testing.T) { transport *Gnmi } type args struct { - params []interface{} - runEndpoint bool + payload change.Payload } tests := []struct { name string fields fields args args - want interface{} wantErr bool }{ { name: "uninitialised", fields: fields{&Gnmi{}}, args: args{ - params: nil, + payload: change.Payload{}, }, - want: nil, wantErr: true, }, // TODO: Positive test cases } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := tt.fields.transport.Set(context.Background(), tt.args.params...) + err := tt.fields.transport.Set(context.Background(), tt.args.payload) if (err != nil) != tt.wantErr { t.Errorf("Set() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("Set() got = %v, want %v", got, tt.want) } }) } @@ -308,7 +307,6 @@ func TestGnmi_Subscribe(t *testing.T) { type fields struct { SetNode func(schema *yang.Entry, root interface{}, path *gpb.Path, val interface{}, opts ...ytypes.SetNodeOpt) error RespChan chan *gpb.SubscribeResponse - config *gnmi.Config } type args struct { ctx context.Context @@ -336,7 +334,6 @@ func TestGnmi_Type(t *testing.T) { type fields struct { SetNode func(schema *yang.Entry, root interface{}, path *gpb.Path, val interface{}, opts ...ytypes.SetNodeOpt) error RespChan chan *gpb.SubscribeResponse - config *gnmi.Config } tests := []struct { name string @@ -436,7 +433,7 @@ func TestGnmi_getWithRequest(t *testing.T) { func TestNewGnmiTransport(t *testing.T) { type args struct { - opts *GnmiTransportOptions + opts *tpb.TransportOption } tests := []struct { name string @@ -445,43 +442,14 @@ func TestNewGnmiTransport(t *testing.T) { wantErr bool }{ { - name: "default", - args: args{opts: &GnmiTransportOptions{ - Config: gnmi.Config{ - Username: "test", - Password: "test", - Addr: "localhost:13371", - Encoding: gpb.Encoding_PROTO, - }, - }}, - want: &Gnmi{ - Options: &GnmiTransportOptions{ - Config: gnmi.Config{ - Username: "test", - Password: "test", - Addr: "localhost:13371", - Encoding: gpb.Encoding_PROTO, - }, - }, - client: nil, - }, - wantErr: false, - }, - { - name: "unsupported compression", - args: args{opts: &GnmiTransportOptions{Config: gnmi.Config{Compression: "brotli"}}}, - want: nil, - wantErr: true, - }, - { - name: "certificate error no key file", - args: args{opts: &GnmiTransportOptions{Config: gnmi.Config{TLS: true, CertFile: "invalid", KeyFile: ""}}}, - want: nil, - wantErr: true, - }, - { - name: "certificate error no ca file", - args: args{opts: &GnmiTransportOptions{Config: gnmi.Config{TLS: true, CAFile: "invalid"}}}, + name: "unsupported compression", + args: args{ + opts: &tpb.TransportOption{ + TransportOption: &tpb.TransportOption_GnmiTransportOption{ + GnmiTransportOption: &tpb.GnmiTransportOption{ + Compression: "brotli", + }, + }}}, want: nil, wantErr: true, }, @@ -491,16 +459,20 @@ func TestNewGnmiTransport(t *testing.T) { if tt.name == "default" { startGnmiTarget <- gnmiConfig.Addr } - got, err := NewGnmiTransport(tt.args.opts) + + got, err := newGnmiTransport(tt.args.opts, NewSBI(spb.Type_OPENCONFIG)) if (err != nil) != tt.wantErr { t.Errorf("NewGnmiTransport() error = %v, wantErr %v", err, tt.wantErr) return } if tt.name == "default" && got != nil { tt.want.client = got.client + tt.want.config = got.config + tt.want.SetNode = got.SetNode + tt.want.RespChan = got.RespChan } if !reflect.DeepEqual(got, tt.want) { - t.Errorf("NewGnmiTransport() got = %v, want %v", got, tt.want) + t.Errorf("NewGnmiTransport() got = %#v, want %#v", got, tt.want) } if tt.name == "default" { stopGnmiTarget <- true @@ -508,63 +480,3 @@ func TestNewGnmiTransport(t *testing.T) { }) } } - -func TestGnmi_set(t *testing.T) { - transport := mockTransport() - mockResponse := &gpb.SetResponse{} - - transport.client.(*mocks.GNMIClient). - On("NewContext", mockContext, mock.Anything). - Return(mockContext) - - transport.client.(*mocks.GNMIClient). - On("Set", mockContext, mock.Anything, mock.Anything). - Return(mockResponse, nil) - - type fields struct { - transport *Gnmi - } - type args struct { - ctx context.Context - setOps []*gnmi.Operation - exts []*gnmi_ext.Extension - } - tests := []struct { - name string - fields fields - args args - want *gpb.SetResponse - - wantErr bool - }{ - { - name: "default", - fields: fields{transport: &transport}, - args: args{ - ctx: context.Background(), - setOps: []*gnmi.Operation{ - { - Type: "update", - Path: []string{"interfaces", "interface", "name"}, - Val: "test0", - }, - }, - exts: nil, - }, - want: &gpb.SetResponse{}, - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := tt.fields.transport.set(tt.args.ctx, tt.args.setOps, tt.args.exts...) - if (err != nil) != tt.wantErr { - t.Errorf("set() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("set() got = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/nucleus/http.go b/nucleus/http.go deleted file mode 100644 index 56ad4cb0af707662e72656e1a7b6a4fa0a88f046..0000000000000000000000000000000000000000 --- a/nucleus/http.go +++ /dev/null @@ -1,208 +0,0 @@ -package nucleus - -import ( - "code.fbi.h-da.de/cocsn/gosdn/forks/goarista/gnmi" - "context" - "fmt" - "github.com/google/uuid" - gpb "github.com/openconfig/gnmi/proto/gnmi" - log "github.com/sirupsen/logrus" - "net/http" - "net/url" - "time" -) - -func stopHttpServer() error { - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() - log.Info("shutting down http server") - return c.httpServer.Shutdown(ctx) -} - -func registerHttpHandler() { - defer func() { - if r := recover(); r != nil { - fmt.Println("Recovered in f", r) - } - }() - http.HandleFunc("/api", httpHandler) - http.HandleFunc("/livez", healthCheck) - http.HandleFunc("/readyz", readynessCheck) -} - -// deprecated -func httpAPI() error { - registerHttpHandler() - c.httpServer = &http.Server{Addr: ":8080"} - go func() { - log.Info(c.httpServer.ListenAndServe()) - }() - return nil -} - -func healthCheck(writer http.ResponseWriter, request *http.Request) { - writer.WriteHeader(http.StatusOK) -} - -func readynessCheck(writer http.ResponseWriter, request *http.Request) { - writer.WriteHeader(http.StatusOK) -} - -// nolint -func httpHandler(writer http.ResponseWriter, request *http.Request) { - log.WithFields(log.Fields{ - "request": request, - }).Debug("incoming request") - - query, err := url.ParseQuery(request.URL.RawQuery) - if err != nil { - log.Error(err) - writer.WriteHeader(http.StatusBadRequest) - return - } - - - id, err := uuid.Parse(query.Get("uuid")) - if err != nil { - if err.Error() != "invalid UUID length: 0" { - log.Error(err) - } - } - - pid, err := uuid.Parse(query.Get("pnd")) - if err != nil { - if err.Error() != "invalid UUID length: 0" { - log.Error(err) - } - } - - sid, err := uuid.Parse(query.Get("sbi")) - if err != nil { - if err.Error() != "invalid UUID length: 0" { - log.Error(err) - } - } - - var pnd PrincipalNetworkDomain - var sbi SouthboundInterface - if query.Get("q") != "init" && query.Get("q") != "getIDs" { - pnd, err = c.pndc.get(pid) - if err != nil { - log.Error(err) - writer.WriteHeader(http.StatusInternalServerError) - return - } - sbic := pnd.GetSBIs() - sbi, err = sbic.(*sbiStore).get(sid) - if err != nil { - log.WithFields(log.Fields{ - "requested uuid": sid, - "available uuids": sbic.(*sbiStore).UUIDs(), - }).Error(err) - writer.WriteHeader(http.StatusInternalServerError) - return - } - } - - switch query.Get("q") { - case "addDevice": - d, err := NewDevice(sbi, &GnmiTransportOptions{ - Config: gnmi.Config{ - Addr: query.Get("address"), - Password: query.Get("password"), - Username: query.Get("username"), - Encoding: gpb.Encoding_JSON_IETF, - }, - SetNode: sbi.SetNode(), - Unmarshal: sbi.(*OpenConfig).Unmarshal(), - RespChan: make(chan *gpb.SubscribeResponse), - }) - err = pnd.AddDevice(d) - if err != nil { - writer.WriteHeader(http.StatusInternalServerError) - log.Error(err) - return - } - writer.WriteHeader(http.StatusCreated) - fmt.Fprintf(writer, "device added\n") - fmt.Fprintf(writer, "UUID: %v\n", d.UUID) - case "request": - err = pnd.Request(id, query.Get("path")) - if err != nil { - switch err.(type) { - case *ErrNotFound: - writer.WriteHeader(http.StatusNotFound) - default: - writer.WriteHeader(http.StatusInternalServerError) - } - log.Error(err) - return - } - writer.WriteHeader(http.StatusOK) - case "requestAll": - err = pnd.RequestAll(query.Get("path")) - if err != nil { - switch err.(type) { - case *ErrNotFound: - writer.WriteHeader(http.StatusNotFound) - default: - writer.WriteHeader(http.StatusInternalServerError) - } - log.Error(err) - return - } - writer.WriteHeader(http.StatusOK) - case "getDevice": - device, err := pnd.MarshalDevice(id) - if err != nil { - switch err.(type) { - case *ErrNotFound: - writer.WriteHeader(http.StatusNotFound) - default: - writer.WriteHeader(http.StatusInternalServerError) - } - log.Error(err) - return - } - writer.Header().Set("Content-Type", "application/json") - fmt.Fprintf(writer, "%v", device) - case "getIDs": - writeIDs := func(typ string, ids []uuid.UUID) { - fmt.Fprintf(writer, "%v:\n", typ) - for i, id := range ids { - fmt.Fprintf(writer, "%v: %v\n", i+1, id) - } - } - pnds := c.pndc.UUIDs() - writeIDs("PNDs", pnds) - writeIDs("SBIs", c.sbic.UUIDs()) - for _,id := range pnds{ - p, err := c.pndc.get(id) - if err != nil { - writer.WriteHeader(http.StatusInternalServerError) - log.Error(err) - return - } - writeIDs("Devices", p.(*pndImplementation).devices.UUIDs()) - } - case "init": - writeIDs := func(typ string, ids []uuid.UUID) { - for _, id := range ids { - fmt.Fprintf(writer, "%v", id) - } - } - writeIDs("PNDs", c.pndc.UUIDs()) - writeIDs("SBIs", c.sbic.UUIDs()) - case "set": - resp, err := pnd.(*pndImplementation).Set(id, query.Get("path"), query.Get("value")) - if err != nil { - writer.WriteHeader(http.StatusInternalServerError) - log.Error(err) - return - } - writer.WriteHeader(http.StatusOK) - fmt.Fprintln(writer, resp) - default: - writer.WriteHeader(http.StatusBadRequest) - } -} diff --git a/nucleus/http_test.go b/nucleus/http_test.go deleted file mode 100644 index 9efa72110a1fe89cf1507424d147e7faac6fd71b..0000000000000000000000000000000000000000 --- a/nucleus/http_test.go +++ /dev/null @@ -1,171 +0,0 @@ -package nucleus - -import ( - "code.fbi.h-da.de/cocsn/gosdn/mocks" - "errors" - "github.com/google/uuid" - log "github.com/sirupsen/logrus" - "github.com/stretchr/testify/mock" - "net/http" - "testing" -) - -func testSetupHTTP() { - sbi = &OpenConfig{id: defaultSbiID} - sbi.Schema() - var err error - pnd, err = NewPND("test", "test pnd", defaultPndID, sbi) - if err != nil { - log.Fatal(err) - } - d = mockDevice() - tr := d.Transport.(*mocks.Transport) - mockError := errors.New("mock error") - tr.On("Get", mockContext, "/system/config/hostname").Return(mock.Anything, nil) - tr.On("Get", mockContext, "error").Return(mock.Anything, mockError) - tr.On("Set", mockContext, mock.Anything).Return(mock.Anything, nil) - tr.On("ProcessResponse", mock.Anything, mock.Anything, mock.Anything).Return(nil) - if err := pnd.AddDevice(&d); err != nil { - log.Fatal(err) - } - args = "&uuid=" + mdid.String() + "&pnd=" + defaultPndID.String() + "&sbi=" + defaultSbiID.String() - argsNotFound = "&uuid=" + uuid.New().String() + "&pnd=" + defaultPndID.String() + "&sbi=" + defaultSbiID.String() - if err := c.sbic.add(sbi); err != nil { - log.Fatal(err) - } - if err := c.pndc.add(pnd); err != nil { - log.Fatal(err) - } -} - -func Test_httpApi(t *testing.T) { - if testing.Short() { - t.Skip("this test is executed separately") - } - tests := []struct { - name string - request string - want *http.Response - wantErr bool - }{ - { - name: "liveliness indicator", - request: apiEndpoint + "/livez", - want: &http.Response{StatusCode: http.StatusOK}, - wantErr: false, - }, - { - name: "readyness indicator", - request: apiEndpoint + "/readyz", - want: &http.Response{StatusCode: http.StatusOK}, - wantErr: false, - }, - { - name: "init", - request: apiEndpoint + "/api?q=init", - want: &http.Response{StatusCode: http.StatusOK}, - wantErr: false, - }, - { - name: "get-ids", - request: apiEndpoint + "/api?q=getIDs", - want: &http.Response{StatusCode: http.StatusOK}, - wantErr: false, - }, - { - name: "add-device", - request: apiEndpoint + "/api?q=addDevice" + args, - want: &http.Response{StatusCode: http.StatusCreated}, - wantErr: false, - }, - { - name: "request", - request: apiEndpoint + "/api?q=request" + args + "&path=/system/config/hostname", - want: &http.Response{StatusCode: http.StatusOK}, - wantErr: false, - }, - { - name: "request not found", - request: apiEndpoint + "/api?q=request" + argsNotFound + "&path=/system/config/hostname", - want: &http.Response{StatusCode: http.StatusNotFound}, - wantErr: false, - }, - { - name: "request internal server error", - request: apiEndpoint + "/api?q=request" + args + "&path=error", - want: &http.Response{StatusCode: http.StatusInternalServerError}, - wantErr: false, - }, - { - name: "request-all", - request: apiEndpoint + "/api?q=requestAll" + args + "&path=/system/config/hostname", - want: &http.Response{StatusCode: http.StatusOK}, - wantErr: false, - }, - { - name: "request-all internal server error", - request: apiEndpoint + "/api?q=requestAll" + args + "&path=error", - want: &http.Response{StatusCode: http.StatusInternalServerError}, - wantErr: false, - }, - - { - name: "get-device", - request: apiEndpoint + "/api?q=getDevice" + args, - want: &http.Response{StatusCode: http.StatusOK}, - wantErr: false, - }, - { - name: "get-device not found", - request: apiEndpoint + "/api?q=getDevice" + argsNotFound, - want: &http.Response{StatusCode: http.StatusNotFound}, - wantErr: false, - }, - { - name: "set", - request: apiEndpoint + "/api?q=set" + args + "&path=/system/config/hostname&value=ceos3000", - want: &http.Response{StatusCode: http.StatusOK}, - wantErr: false, - }, - { - name: "internal server errror: wrong pnd", - request: apiEndpoint + "/api?pnd=" + uuid.New().String(), - want: &http.Response{StatusCode: http.StatusInternalServerError}, - wantErr: false, - }, - { - name: "internal server errror: wrong sbi", - request: apiEndpoint + "/api?sbi=" + uuid.New().String(), - want: &http.Response{StatusCode: http.StatusInternalServerError}, - wantErr: false, - }, - } - coreLock.Lock() - if err := httpAPI(); err != nil { - t.Errorf("httpApi() error = %v", err) - return - } - coreLock.Unlock() - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := http.Get(tt.request) - if (err != nil) != tt.wantErr { - t.Errorf("httpApi() error = %v, wantErr %v", err, tt.wantErr) - return - } - if got.StatusCode != tt.want.StatusCode { - t.Errorf("httpApi() got: %v, want %v", got.StatusCode, tt.want.StatusCode) - } - if tt.name == "add-device" { - for k := range pnd.(*pndImplementation).devices.store { - if k != mdid { - if err := pnd.RemoveDevice(k); err != nil { - t.Error(err) - return - } - } - } - } - }) - } -} diff --git a/nucleus/initialise_test.go b/nucleus/initialise_test.go index 6c90b054e44d009e03542821ced09f46cd65bb49..f0d9b10981d71eb2b8b6c0617aa6809b7c064c17 100644 --- a/nucleus/initialise_test.go +++ b/nucleus/initialise_test.go @@ -1,22 +1,26 @@ package nucleus import ( - "code.fbi.h-da.de/cocsn/gosdn/forks/goarista/gnmi" - "code.fbi.h-da.de/cocsn/gosdn/mocks" - "code.fbi.h-da.de/cocsn/gosdn/nucleus/util/proto" - "code.fbi.h-da.de/cocsn/gosdn/test" "context" + "os" + "testing" + + "code.fbi.h-da.de/danet/gosdn/interfaces/device" + "code.fbi.h-da.de/danet/gosdn/store" + + tpb "code.fbi.h-da.de/danet/api/go/gosdn/transport" + + "code.fbi.h-da.de/danet/forks/goarista/gnmi" + "code.fbi.h-da.de/danet/gosdn/mocks" + "code.fbi.h-da.de/danet/gosdn/nucleus/util/proto" + "code.fbi.h-da.de/danet/gosdn/test" "github.com/google/uuid" gpb "github.com/openconfig/gnmi/proto/gnmi" log "github.com/sirupsen/logrus" "github.com/stretchr/testify/mock" pb "google.golang.org/protobuf/proto" - "os" - "testing" ) -const apiEndpoint = "http://localhost:8080" - // UUIDs for test cases var did uuid.UUID var mdid uuid.UUID @@ -25,17 +29,13 @@ var defaultPndID uuid.UUID var ocUUID uuid.UUID var iid uuid.UUID var altIid uuid.UUID +var cuid uuid.UUID -var sbi SouthboundInterface -var pnd PrincipalNetworkDomain var gnmiMessages map[string]pb.Message var gnmiConfig *gnmi.Config -var d Device var startGnmiTarget chan string var stopGnmiTarget chan bool -var args string -var argsNotFound string var mockContext = mock.MatchedBy(func(ctx context.Context) bool { return true }) @@ -68,9 +68,7 @@ func TestMain(m *testing.M) { } } readTestUUIDs() - testSetupGnmi() - testSetupHTTP() os.Exit(m.Run()) } @@ -89,19 +87,18 @@ func mockTransport() Gnmi { RespChan: make(chan *gpb.SubscribeResponse), Options: newGnmiTransportOptions(), client: &mocks.GNMIClient{}, + config: gnmiConfig, } } -func newGnmiTransportOptions() *GnmiTransportOptions { - return &GnmiTransportOptions{ - Config: gnmi.Config{ - Username: "test", - Password: "test", - Addr: "localhost:13371", - Encoding: gpb.Encoding_PROTO, +func newGnmiTransportOptions() *tpb.TransportOption { + return &tpb.TransportOption{ + Address: "localhost:13371", + Username: "test", + Password: "test", + TransportOption: &tpb.TransportOption_GnmiTransportOption{ + GnmiTransportOption: &tpb.GnmiTransportOption{}, }, - SetNode: nil, - RespChan: make(chan *gpb.SubscribeResponse), } } @@ -111,48 +108,53 @@ func readTestUUIDs() { if err != nil { log.Fatal(err) } - mdid, err = uuid.Parse("688a264e-5f85-40f8-bd13-afc42fcd5c7a") if err != nil { log.Fatal(err) } - defaultSbiID, err = uuid.Parse("b70c8425-68c7-4d4b-bb5e-5586572bd64b") if err != nil { log.Fatal(err) } - defaultPndID, err = uuid.Parse("b4016412-eec5-45a1-aa29-f59915357bad") if err != nil { log.Fatal(err) } - ocUUID, err = uuid.Parse("5e252b70-38f2-4c99-a0bf-1b16af4d7e67") if err != nil { log.Fatal(err) } iid, err = uuid.Parse("8495a8ac-a1e8-418e-b787-10f5878b2690") + if err != nil { + log.Fatal(err) + } altIid, err = uuid.Parse("edc5de93-2d15-4586-b2a7-fb1bc770986b") if err != nil { log.Fatal(err) } + cuid, err = uuid.Parse("3e8219b0-e926-400d-8660-217f2a25a7c6") + if err != nil { + log.Fatal(err) + } } -func mockDevice() Device { - return Device{ +func mockDevice() device.Device { + sbi := &OpenConfig{} + return &CommonDevice{ UUID: mdid, - GoStruct: nil, - SBI: &OpenConfig{}, - Transport: &mocks.Transport{}, + GoStruct: sbi.Schema().Root, + sbi: sbi, + transport: &mocks.Transport{}, } } func newPnd() pndImplementation { return pndImplementation{ - name: "default", - description: "default test pnd", - sbic: sbiStore{store{}}, - devices: deviceStore{store{}}, - id: defaultPndID, + Name: "default", + Description: "default test pnd", + sbic: store.NewSbiStore(), + devices: store.NewDeviceStore(defaultPndID), + changes: store.NewChangeStore(), + Id: defaultPndID, } } diff --git a/nucleus/metrics.go b/nucleus/metrics.go new file mode 100644 index 0000000000000000000000000000000000000000..fb151fde466811a7e4b00c497ea636c50cffebf9 --- /dev/null +++ b/nucleus/metrics.go @@ -0,0 +1,56 @@ +package nucleus + +import ( + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" +) + +var ( + deviceCreationsTotal = promauto.NewCounterVec( + prometheus.CounterOpts{ + Name: "device_creations_total", + Help: "Total number of created devices", + }, + []string{"type"}, + ) + + deviceCreationDurationSecondsTotal = promauto.NewCounterVec( + prometheus.CounterOpts{ + Name: "device_creation_duration_seconds_total", + Help: "Total time needed to create devices", + }, + []string{"type"}, + ) + + deviceCreationDurationSeconds = promauto.NewHistogramVec( + prometheus.HistogramOpts{ + Name: "device_creation_duration_seconds", + Help: "Histogram of device creation times", + }, + []string{"type"}, + ) + + deviceDeletionsTotal = promauto.NewCounterVec( + prometheus.CounterOpts{ + Name: "device_deletions_total", + Help: "Total number of deleted devices", + }, + []string{"type"}, + ) + + deviceDeletionDurationSecondsTotal = promauto.NewCounterVec( + prometheus.CounterOpts{ + Name: "device_deletion_duration_seconds_total", + Help: "Total time needed to delete devices", + }, + []string{"type"}, + ) + + deviceDeletionDurationSeconds = promauto.NewHistogramVec( + prometheus.HistogramOpts{ + Name: "device_deletion_duration_seconds", + Help: "Histogram of device deletion times", + }, + []string{"type"}, + ) +) diff --git a/nucleus/principalNetworkDomain.go b/nucleus/principalNetworkDomain.go index ebb372081a3636a2e0629200c9b56822d11981ae..2c7d845514419c74322e3381b71e4855a72f4ac6 100644 --- a/nucleus/principalNetworkDomain.go +++ b/nucleus/principalNetworkDomain.go @@ -1,77 +1,135 @@ package nucleus import ( - "code.fbi.h-da.de/cocsn/gosdn/forks/goarista/gnmi" "context" - log "github.com/sirupsen/logrus" - "encoding/json" + "io" + "os" + "plugin" + "time" + + "code.fbi.h-da.de/danet/gosdn/metrics" + "code.fbi.h-da.de/danet/gosdn/nucleus/types" + + cpb "code.fbi.h-da.de/danet/api/go/gosdn/csbi" + ppb "code.fbi.h-da.de/danet/api/go/gosdn/pnd" + spb "code.fbi.h-da.de/danet/api/go/gosdn/southbound" + tpb "code.fbi.h-da.de/danet/api/go/gosdn/transport" + "google.golang.org/protobuf/proto" + + "code.fbi.h-da.de/danet/forks/goarista/gnmi" + "code.fbi.h-da.de/danet/gosdn/interfaces/change" + "code.fbi.h-da.de/danet/gosdn/interfaces/device" + "code.fbi.h-da.de/danet/gosdn/interfaces/networkdomain" + "code.fbi.h-da.de/danet/gosdn/interfaces/southbound" + si "code.fbi.h-da.de/danet/gosdn/interfaces/store" + "code.fbi.h-da.de/danet/gosdn/nucleus/errors" + + "code.fbi.h-da.de/danet/gosdn/store" + "github.com/google/uuid" + "github.com/openconfig/ygot/ygot" + "github.com/openconfig/ygot/ytypes" + "github.com/prometheus/client_golang/prometheus" + log "github.com/sirupsen/logrus" ) -// PrincipalNetworkDomain provides an -// interface for PND implementations -type PrincipalNetworkDomain interface { - Destroy() error - AddSbi(interface{}) error - RemoveSbi(uuid.UUID) error - AddDevice(interface{}) error - RemoveDevice(uuid.UUID) error - Request(uuid.UUID, string) error - RequestAll(string) error - GetName() string - GetDescription() string - MarshalDevice(uuid.UUID) (string, error) - ContainsDevice(uuid.UUID) bool - GetSBIs() interface{} - ID() uuid.UUID +// NewPND creates a Principle Network Domain +func NewPND(name, description string, id uuid.UUID, sbi southbound.SouthboundInterface, c cpb.CsbiClient, callback func(uuid.UUID, chan store.DeviceDetails)) (networkdomain.NetworkDomain, error) { + pnd := &pndImplementation{ + Name: name, + Description: description, + sbic: store.NewSbiStore(), + devices: store.NewDeviceStore(id), + changes: store.NewChangeStore(), + Id: id, + + csbiClient: c, + callback: callback, + } + + if err := pnd.sbic.Add(sbi); err != nil { + return nil, err + } + + if err := pnd.loadStoredDevices(); err != nil { + return nil, err + } + + return pnd, nil } type pndImplementation struct { - name string - description string - sbic sbiStore - devices deviceStore - id uuid.UUID + Name string `json:"name,omitempty"` + Description string `json:"description,omitempty"` + sbic *store.SbiStore + devices *store.DeviceStore + changes *store.ChangeStore + //nolint + Id uuid.UUID `json:"id,omitempty"` + + csbiClient cpb.CsbiClient + callback func(uuid.UUID, chan store.DeviceDetails) } -// NewPND creates a Principle Network Domain -func NewPND(name, description string, id uuid.UUID, sbi SouthboundInterface) (PrincipalNetworkDomain, error) { - pnd := &pndImplementation{ - name: name, - description: description, - sbic: sbiStore{store{}}, - devices: deviceStore{store{}}, - id: id, +func (pnd *pndImplementation) PendingChanges() []uuid.UUID { + return pnd.changes.Pending() +} + +func (pnd *pndImplementation) CommittedChanges() []uuid.UUID { + return pnd.changes.Committed() +} + +func (pnd *pndImplementation) ConfirmedChanges() []uuid.UUID { + return pnd.changes.Confirmed() +} + +func (pnd *pndImplementation) GetChange(cuid uuid.UUID) (change.Change, error) { + return pnd.changes.GetChange(cuid) +} + +func (pnd *pndImplementation) Commit(u uuid.UUID) error { + ch, err := pnd.changes.GetChange(u) + if err != nil { + return err } - if err := pnd.sbic.add(sbi); err != nil { - return nil, &ErrAlreadyExists{item: sbi} + return ch.Commit() +} + +func (pnd *pndImplementation) Confirm(u uuid.UUID) error { + ch, err := pnd.changes.GetChange(u) + if err != nil { + return err } - return pnd, nil + return ch.Confirm() } func (pnd *pndImplementation) ID() uuid.UUID { - return pnd.id + return pnd.Id +} + +func (pnd *pndImplementation) Devices() []uuid.UUID { + return pnd.devices.UUIDs() } // GetName returns the name of the PND func (pnd *pndImplementation) GetName() string { - return pnd.name + return pnd.Name } // ContainsDevice checks if the given device uuid is registered for this PND func (pnd *pndImplementation) ContainsDevice(id uuid.UUID) bool { - return pnd.devices.exists(id) + return pnd.devices.Exists(id) } // GetDescription returns the current description of the PND func (pnd *pndImplementation) GetDescription() string { - return pnd.description + return pnd.Description } // GetSBIs returns the registered SBIs -func (pnd *pndImplementation) GetSBIs() interface{} { - return &pnd.sbic +func (pnd *pndImplementation) GetSBIs() si.Store { + return pnd.sbic } // Destroy destroys the PND @@ -80,37 +138,89 @@ func (pnd *pndImplementation) Destroy() error { } // AddSbi adds a SBI to the PND which will be supported -func (pnd *pndImplementation) AddSbi(sbi interface{}) error { - s, ok := sbi.(SouthboundInterface) - if !ok { - return &ErrInvalidTypeAssertion{ - v: sbi, - t: "Device", - } - } +func (pnd *pndImplementation) AddSbi(s southbound.SouthboundInterface) error { return pnd.addSbi(s) } -// AddSbi removes a SBI from the PND -// TODO: this should to recursivly through -// devices and remove the devices using -// this SBI +// RemoveSbi removes a SBI and all the associated devices from the PND func (pnd *pndImplementation) RemoveSbi(id uuid.UUID) error { + associatedDevices, err := pnd.devices.GetDevicesAssociatedWithSbi(id) + if err != nil { + return err + } + // range over associated devices and remove each one of them + for _, d := range associatedDevices { + if err := pnd.removeDevice(d.ID()); err != nil { + return err + } + } return pnd.removeSbi(id) } //AddDevice adds a new device to the PND -func (pnd *pndImplementation) AddDevice(device interface{}) error { - d, ok := device.(*Device) - if !ok { - return &ErrInvalidTypeAssertion{ - v: device, - t: "Device", +func (pnd *pndImplementation) AddDevice(name string, opt *tpb.TransportOption, sid uuid.UUID) error { + labels := prometheus.Labels{"type": opt.Type.String()} + start := metrics.StartHook(labels, deviceCreationsTotal) + defer metrics.FinishHook(labels, start, deviceCreationDurationSecondsTotal, deviceCreationDurationSeconds) + var sbi southbound.SouthboundInterface + switch t := opt.Type; t { + case spb.Type_CONTAINERISED: + return pnd.handleCsbiEnrolment(name, opt) + case spb.Type_PLUGIN: + var err error + sbi, err = pnd.requestPlugin(name, opt) + if err != nil { + return err + } + default: + var err error + sbi, err = pnd.sbic.GetSBI(sid) + if err != nil { + return err } } + + d, err := NewDevice(name, uuid.Nil, opt, sbi) + if err != nil { + return err + } + return pnd.addDevice(d) +} + +//AddDeviceFromStore adds a new device to the PND +func (pnd *pndImplementation) AddDeviceFromStore(name string, deviceUUID uuid.UUID, opt *tpb.TransportOption, sid uuid.UUID) error { + if opt.Type == spb.Type_CONTAINERISED { + return pnd.handleCsbiEnrolment(name, opt) + } + + sbi, err := pnd.sbic.GetSBI(sid) + if err != nil { + return err + } + + d, err := NewDevice(name, deviceUUID, opt, sbi) + if err != nil { + return err + } return pnd.addDevice(d) } +func (pnd *pndImplementation) GetDevice(identifier string) (device.Device, error) { + d, err := pnd.devices.GetDevice(store.FromString(identifier)) + if err != nil { + return nil, err + } + + copiedGoStruct, err := ygot.DeepCopy(d.Model()) + if err != nil { + return nil, err + } + + copiedDevice := &CommonDevice{name: d.Name(), UUID: d.ID(), GoStruct: copiedGoStruct} + + return copiedDevice, nil +} + // RemoveDevice removes a device from the PND func (pnd *pndImplementation) RemoveDevice(uuid uuid.UUID) error { return pnd.removeDevice(uuid) @@ -122,92 +232,334 @@ func destroy() error { return nil } -func (pnd *pndImplementation) addSbi(sbi SouthboundInterface) error { - return pnd.sbic.add(sbi) +func (pnd *pndImplementation) addSbi(sbi southbound.SouthboundInterface) error { + return pnd.sbic.Add(sbi) } func (pnd *pndImplementation) removeSbi(id uuid.UUID) error { - return pnd.sbic.delete(id) + return pnd.sbic.Delete(id) } -func (pnd *pndImplementation) addDevice(device *Device) error { - return pnd.devices.add(device) -} +func (pnd *pndImplementation) addDevice(device device.Device) error { + err := pnd.devices.Add(device, device.Name()) + if err != nil { + return err + } -func (pnd *pndImplementation) getDevice(id uuid.UUID) (*Device, error) { - return pnd.devices.get(id) + return nil } func (pnd *pndImplementation) removeDevice(id uuid.UUID) error { - return pnd.devices.delete(id) + d, err := pnd.devices.GetDevice(id) + if err != nil { + return err + } + labels := prometheus.Labels{"type": d.SBI().SbiIdentifier()} + start := metrics.StartHook(labels, deviceDeletionsTotal) + defer metrics.FinishHook(labels, start, deviceDeletionDurationSecondsTotal, deviceDeletionDurationSeconds) + switch d.(type) { + case *CsbiDevice: + return pnd.handleCsbiDeletion(id) + default: + return pnd.devices.Delete(id) + } } -func (pnd *pndImplementation) MarshalDevice(uuid uuid.UUID) (string, error) { - d, err := pnd.getDevice(uuid) +func (pnd *pndImplementation) MarshalDevice(identifier string) (string, error) { + foundDevice, err := pnd.devices.GetDevice(store.FromString(identifier)) if err != nil { return "", err } - jsonTree, err := json.MarshalIndent(d.GoStruct, "", "\t") + + jsonTree, err := json.MarshalIndent(foundDevice.Model(), "", "\t") if err != nil { return "", err } log.WithFields(log.Fields{ - "pnd": pnd.id, - "device": uuid, + "pnd": pnd.Id, + "Identifier": identifier, + "Name": foundDevice.Name, }).Info("marshalled device") + return string(jsonTree), nil } // Request sends a get request to a specific device -func (pnd *pndImplementation) Request(uuid uuid.UUID, path string) error { - d, err := pnd.getDevice(uuid) +func (pnd *pndImplementation) Request(uuid uuid.UUID, path string) (proto.Message, error) { + d, err := pnd.devices.GetDevice(store.FromString(uuid.String())) if err != nil { - return err + return nil, err } ctx := context.Background() - res, err := d.Transport.Get(ctx, path) + res, err := d.Transport().Get(ctx, path) if err != nil { - return err + return nil, err + } + resp, ok := res.(proto.Message) + if !ok { + return nil, &errors.ErrInvalidTypeAssertion{ + Value: res, + Type: (*proto.Message)(nil), + } } - err = d.Transport.ProcessResponse(res, d.GoStruct, d.SBI.Schema()) + err = d.ProcessResponse(resp) if err != nil { - return err + return nil, err } - return nil + return resp, nil } // RequestAll sends a request for all registered devices func (pnd *pndImplementation) RequestAll(path string) error { for _, k := range pnd.devices.UUIDs() { - if err := pnd.Request(k, path); err != nil { + _, err := pnd.Request(k, path) + if err != nil { return err } } log.WithFields(log.Fields{ - "pnd": pnd.id, + "pnd": pnd.Id, "path": path, }).Info("sent request to all devices") return nil } -// Set sets the value to the given device path -// TODO: Design commit/confirm mechanism -func (pnd *pndImplementation) Set(uuid uuid.UUID, path string, value string) (interface{}, error) { - d, err := pnd.getDevice(uuid) +// ChangeOND creates a change from the provided Operation, path and value. +// The Change is Pending and times out after the specified timeout period +func (pnd *pndImplementation) ChangeOND(duid uuid.UUID, operation ppb.ApiOperation, path string, value ...string) (uuid.UUID, error) { + d, err := pnd.devices.GetDevice(duid) + if err != nil { + return uuid.Nil, err + } + cpy, err := ygot.DeepCopy(d.Model()) + ygot.BuildEmptyTree(cpy) + if err != nil { + return uuid.Nil, err + } + + p, err := ygot.StringToStructuredPath(path) + if err != nil { + return uuid.Nil, err + } + + if operation != ppb.ApiOperation_DELETE && len(value) != 1 { + return uuid.Nil, &errors.ErrInvalidParameters{ + Func: pnd.ChangeOND, + Param: value, + } + } + switch operation { + case ppb.ApiOperation_UPDATE, ppb.ApiOperation_REPLACE: + typedValue := gnmi.TypedValue(value[0]) + if err := ytypes.SetNode(d.SBI().Schema().RootSchema(), cpy, p, typedValue); err != nil { + return uuid.Nil, err + } + case ppb.ApiOperation_DELETE: + if err := ytypes.DeleteNode(d.SBI().Schema().RootSchema(), cpy, p); err != nil { + return uuid.Nil, err + } + default: + return uuid.Nil, &errors.ErrOperationNotSupported{Op: operation} + } + + ygot.PruneEmptyBranches(cpy) + callback := func(original ygot.GoStruct, modified ygot.GoStruct) error { + ctx := context.WithValue(context.Background(), types.CtxKeyOperation, operation) // nolint + payload := change.Payload{Original: original, Modified: modified} + return d.Transport().Set(ctx, payload) + } + ch := NewChange(duid, d.Model(), cpy, callback) + if err := pnd.changes.Add(ch); err != nil { + return uuid.Nil, err + } + return ch.cuid, nil +} + +// nolint will be implemented in the near future +func handleRollbackError(id uuid.UUID, err error) { + log.Error(err) + // TODO: Notion of invalid state needed. +} + +func (pnd *pndImplementation) handleCsbiDeletion(id uuid.UUID) error { + log.Infof("csbi deletion triggered for %v", id) + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + req := &cpb.DeleteRequest{ + Timestamp: time.Now().UnixNano(), + Did: []string{id.String()}, + } + resp, err := pnd.csbiClient.Delete(ctx, req) + if err != nil { + return err + } + log.WithFields(log.Fields{ + "uuid": id, + "status": resp.Status, + }).Info("csbi deleted") + return nil +} + +func (pnd *pndImplementation) handleCsbiEnrolment(name string, opt *tpb.TransportOption) error { + ctx, cancel := context.WithTimeout(context.Background(), time.Minute*5) + defer cancel() + req := &cpb.CreateRequest{ + Timestamp: time.Now().UnixNano(), + TransportOption: []*tpb.TransportOption{opt}, + } + resp, err := pnd.csbiClient.Create(ctx, req) + if err != nil { + return err + } + for _, d := range resp.Deployments { + if err := pnd.createCsbiDevice(ctx, name, d, opt); err != nil { + log.Error(err) + } + } + return nil +} + +func (pnd *pndImplementation) createCsbiDevice(ctx context.Context, name string, d *cpb.Deployment, opt *tpb.TransportOption) error { + defer func() { + if r := recover(); r != nil { + log.Errorf("recovered in sbi enrolment: %v", r) + } + }() + id, err := uuid.Parse(d.Id) + if err != nil { + return err + } + ch := make(chan store.DeviceDetails, 1) + pnd.callback(id, ch) + tickatus := time.NewTicker(time.Minute * 1) + go func() { + select { + case <-tickatus.C: + log.WithFields(log.Fields{ + "id": d.Id, + "err": ctx.Err(), + }).Error("csbi handshake timed out") + case deviceDetails := <-ch: + log.Infof("syn from csbi %v", deviceDetails.ID) + id, err := uuid.Parse(deviceDetails.ID) + if err != nil { + panic(err) + } + csbiTransportOptions := &tpb.TransportOption{ + Address: deviceDetails.Address, + Username: opt.Username, + Password: opt.Password, + Tls: opt.Tls, + Type: opt.Type, + TransportOption: opt.TransportOption, + } + log.WithField("transport option", csbiTransportOptions).Debug("gosdn gnmi transport options") + d, err := NewDevice(name, uuid.Nil, csbiTransportOptions, csbi) + if err != nil { + panic(err) + } + d.(*CsbiDevice).UUID = id + ch <- store.DeviceDetails{TransportOption: opt} + if err := pnd.devices.Add(d, d.Name()); err != nil { + panic(err) + } + } + pnd.callback(id, nil) + close(ch) + }() + return nil +} + +func (pnd *pndImplementation) requestPlugin(name string, opt *tpb.TransportOption) (southbound.SouthboundInterface, error) { + ctx, cancel := context.WithTimeout(context.Background(), time.Minute*10) + defer cancel() + req := &cpb.CreateRequest{ + Timestamp: time.Now().UnixNano(), + TransportOption: []*tpb.TransportOption{opt}, + } + client, err := pnd.csbiClient.CreatePlugin(ctx, req) if err != nil { return nil, err } - ctx := context.Background() - // TODO: Move to transport dependent func - opts := []interface{}{ - &gnmi.Operation{ - Type: "update", - Origin: "", - Target: "", - Path: gnmi.SplitPath(path), - Val: value, - }, - } - return d.Transport.Set(ctx, opts...) + id := uuid.New() + f, err := os.Create("plugin-" + id.String() + ".so") + if err != nil { + return nil, err + } + defer f.Close() + for { + payload, err := client.Recv() + if err != nil { + if err == io.EOF { + break + } + client.CloseSend() + return nil, err + } + n, err := f.Write(payload.Chunk) + if err != nil { + client.CloseSend() + return nil, err + } + log.WithField("n", n).Trace("wrote bytes") + } + if err := f.Sync(); err != nil { + return nil, err + } + + return loadPlugin(id) +} + +func loadPlugin(id uuid.UUID) (southbound.SouthboundInterface, error) { + p, err := plugin.Open("plugin-" + id.String() + ".so") + if err != nil { + return nil, err + } + + symbol, err := p.Lookup("PluginSymbol") + if err != nil { + return nil, err + } + + var sbi southbound.SouthboundInterface + sbi, ok := symbol.(southbound.SouthboundInterface) + if !ok { + return nil, &errors.ErrInvalidTypeAssertion{ + Value: symbol, + Type: (*southbound.SouthboundInterface)(nil), + } + } + log.WithFields(log.Fields{ + "identifier": sbi.SbiIdentifier(), + "id": sbi.ID(), + "type": sbi.Type(), + }).Trace("plugin information") + return sbi, nil +} + +func (pnd *pndImplementation) loadStoredDevices() error { + devices, err := pnd.devices.Load() + if err != nil { + return err + } + + for _, device := range devices { + err := pnd.AddDeviceFromStore( + device.Name, + device.DeviceID, + &tpb.TransportOption{ + Address: device.TransportAddress, + Username: device.TransportUsername, + Password: device.TransportPassword, + TransportOption: &tpb.TransportOption_GnmiTransportOption{ + GnmiTransportOption: &tpb.GnmiTransportOption{}, + }, + Type: spb.Type_OPENCONFIG, + }, device.SBI) + if err != nil { + return err + } + } + return nil } diff --git a/nucleus/principalNetworkDomain_test.go b/nucleus/principalNetworkDomain_test.go index f02f840bc948d4887983a4beb532808d9e8dc2c7..2aabcd29814271b38539dfbef5def11827ff348e 100644 --- a/nucleus/principalNetworkDomain_test.go +++ b/nucleus/principalNetworkDomain_test.go @@ -1,30 +1,49 @@ package nucleus import ( - "code.fbi.h-da.de/cocsn/gosdn/mocks" - "code.fbi.h-da.de/cocsn/yang-models/generated/openconfig" "errors" - "github.com/google/uuid" - "github.com/stretchr/testify/mock" + "fmt" + "os" "reflect" "testing" + + ppb "code.fbi.h-da.de/danet/api/go/gosdn/pnd" + spb "code.fbi.h-da.de/danet/api/go/gosdn/southbound" + tpb "code.fbi.h-da.de/danet/api/go/gosdn/transport" + "code.fbi.h-da.de/danet/gosdn/interfaces/device" + "code.fbi.h-da.de/danet/gosdn/interfaces/networkdomain" + "code.fbi.h-da.de/danet/gosdn/interfaces/southbound" + "code.fbi.h-da.de/danet/gosdn/mocks" + "code.fbi.h-da.de/danet/gosdn/store" + "code.fbi.h-da.de/danet/yang-models/generated/openconfig" + "github.com/google/uuid" + gpb "github.com/openconfig/gnmi/proto/gnmi" + "github.com/openconfig/ygot/ygot" + log "github.com/sirupsen/logrus" + "github.com/stretchr/testify/mock" ) +func removeExistingPNDStore() { + os.Remove(fmt.Sprintf("stores/device-store-%s.json", defaultPndID)) +} + func TestNewPND(t *testing.T) { - pnd := newPnd() - if err := pnd.addSbi(&OpenConfig{id: defaultSbiID}); err != nil { + removeExistingPNDStore() + + p := newPnd() + if err := p.addSbi(&OpenConfig{id: defaultSbiID}); err != nil { t.Error(err) } type args struct { name string description string - sbi SouthboundInterface + sbi southbound.SouthboundInterface pid uuid.UUID } tests := []struct { name string args args - want PrincipalNetworkDomain + want networkdomain.NetworkDomain wantErr bool }{ { @@ -35,13 +54,13 @@ func TestNewPND(t *testing.T) { sbi: &OpenConfig{id: defaultSbiID}, pid: defaultPndID, }, - want: &pnd, + want: &p, wantErr: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := NewPND(tt.args.name, tt.args.description, tt.args.pid, tt.args.sbi) + got, err := NewPND(tt.args.name, tt.args.description, tt.args.pid, tt.args.sbi, nil, nil) if (err != nil) != tt.wantErr { t.Errorf("NewPND() error = %v, wantErr %v", err, tt.wantErr) return @@ -72,6 +91,8 @@ func Test_destroy(t *testing.T) { func Test_pndImplementation_AddDevice(t *testing.T) { type args struct { device interface{} + name string + opts *tpb.TransportOption } tests := []struct { name string @@ -81,47 +102,40 @@ func Test_pndImplementation_AddDevice(t *testing.T) { { name: "default", args: args{ - device: &Device{ - UUID: did, + name: "fridolin", + opts: &tpb.TransportOption{ + TransportOption: &tpb.TransportOption_GnmiTransportOption{ + GnmiTransportOption: &tpb.GnmiTransportOption{}, + }, }, }, wantErr: false, }, - { - name: "already exists", - args: args{ - device: &Device{ - UUID: did, - }, - }, - wantErr: true, - }, - { - name: "fails wrong type", - args: args{device: &pndImplementation{ - id: did, - }}, - wantErr: true, - }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { pnd := newPnd() + if err := pnd.addSbi(&OpenConfig{id: defaultSbiID}); err != nil { + t.Error(err) + } if tt.name == "already exists" { - pnd.devices.store[did] = &Device{UUID: did} + pnd.devices.Store[did] = tt.args.device.(device.Device) } - err := pnd.AddDevice(tt.args.device) + err := pnd.AddDevice(tt.args.name, tt.args.opts, defaultSbiID) if (err != nil) != tt.wantErr { t.Errorf("AddDevice() error = %v, wantErr %v", err, tt.wantErr) } if tt.name != "fails wrong type" { if err == nil { - _, ok := pnd.devices.store[did] - if !ok { - t.Errorf("AddDevice() Device %v not in device store %v", - tt.args.device, pnd.devices) + d, err := pnd.devices.GetDevice(store.FromString(tt.args.name)) + if err != nil { + t.Errorf("AddDevice() error = %v", err) + return } - if err := pnd.devices.delete(did); err != nil { + if d.Name() != tt.args.name { + t.Errorf("AddDevice() got = %v, want %v", d.Name(), tt.args.name) + } + if err := pnd.devices.Delete(d.ID()); err != nil { t.Error(err) } } @@ -130,9 +144,10 @@ func Test_pndImplementation_AddDevice(t *testing.T) { } } +// TODO: refactor test to use store interface instead if direct access. func Test_pndImplementation_AddSbi(t *testing.T) { type args struct { - sbi interface{} + sbi southbound.SouthboundInterface } tests := []struct { name string @@ -157,21 +172,12 @@ func Test_pndImplementation_AddSbi(t *testing.T) { }, wantErr: true, }, - { - name: "fails wrong type", - args: args{ - sbi: &pndImplementation{ - id: defaultSbiID, - }, - }, - wantErr: true, - }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { pnd := newPnd() if tt.name == "already exists" { - pnd.sbic.store[defaultSbiID] = tt.args.sbi.(*OpenConfig) + pnd.sbic.Store[defaultSbiID] = tt.args.sbi } err := pnd.AddSbi(tt.args.sbi) if (err != nil) != tt.wantErr { @@ -179,12 +185,12 @@ func Test_pndImplementation_AddSbi(t *testing.T) { } if tt.name != "fails wrong type" { if err == nil { - _, ok := pnd.sbic.store[defaultSbiID] + _, ok := pnd.sbic.Store[defaultSbiID] if !ok { t.Errorf("AddSbi() SBI %v not in device store %v", tt.args.sbi, pnd.GetSBIs()) } - if err := pnd.sbic.delete(defaultSbiID); err != nil { + if err := pnd.sbic.Delete(defaultSbiID); err != nil { t.Error(err) } } @@ -194,9 +200,11 @@ func Test_pndImplementation_AddSbi(t *testing.T) { } func Test_pndImplementation_ContainsDevice(t *testing.T) { + removeExistingPNDStore() + type args struct { uuid uuid.UUID - device *Device + device device.Device } tests := []struct { name string @@ -205,29 +213,30 @@ func Test_pndImplementation_ContainsDevice(t *testing.T) { }{ {name: "default", args: args{ uuid: did, - device: &Device{UUID: did}, + device: &CommonDevice{UUID: did}, }, want: true}, {name: "fails", args: args{ uuid: uuid.New(), - device: &Device{UUID: did}, + device: &CommonDevice{UUID: did}, }, want: false}, {name: "fails empty", args: args{ uuid: uuid.New(), - device: &Device{UUID: did}, + device: &CommonDevice{UUID: did}, }, want: false}, } + for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { pnd := newPnd() if tt.name != "fails empty" { - if err := pnd.devices.add(tt.args.device); err != nil { + if err := pnd.devices.Add(tt.args.device, "test"); err != nil { t.Error(err) } } if got := pnd.ContainsDevice(tt.args.uuid); got != tt.want { t.Errorf("ContainsDevice() = %v, want %v", got, tt.want) } - if err := pnd.devices.delete(did); err != nil && tt.name != "fails empty" { + if err := pnd.devices.Delete(did); err != nil && tt.name != "fails empty" { t.Error(err) } }) @@ -238,8 +247,8 @@ func Test_pndImplementation_Destroy(t *testing.T) { type fields struct { name string description string - sbi sbiStore - devices deviceStore + sbi *store.SbiStore + devices *store.DeviceStore } tests := []struct { name string @@ -251,8 +260,8 @@ func Test_pndImplementation_Destroy(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { pnd := &pndImplementation{ - name: tt.fields.name, - description: tt.fields.description, + Name: tt.fields.name, + Description: tt.fields.description, sbic: tt.fields.sbi, devices: tt.fields.devices, } @@ -301,9 +310,9 @@ func Test_pndImplementation_GetSBIs(t *testing.T) { pnd := newPnd() tests := []struct { name string - want *sbiStore + want *store.SbiStore }{ - {name: "default", want: &pnd.sbic}, + {name: "default", want: pnd.sbic}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -315,6 +324,8 @@ func Test_pndImplementation_GetSBIs(t *testing.T) { } func Test_pndImplementation_MarshalDevice(t *testing.T) { + removeExistingPNDStore() + type args struct { uuid uuid.UUID } @@ -331,19 +342,20 @@ func Test_pndImplementation_MarshalDevice(t *testing.T) { wantErr: false, }, } + for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { pnd := newPnd() - d := &Device{ + d := &CommonDevice{ UUID: tt.args.uuid, GoStruct: &openconfig.Device{}, - SBI: nil, - Transport: nil, + sbi: nil, + transport: nil, } if err := pnd.addDevice(d); err != nil { t.Error(err) } - got, err := pnd.MarshalDevice(tt.args.uuid) + got, err := pnd.MarshalDevice(tt.args.uuid.String()) if (err != nil) != tt.wantErr { t.Errorf("MarshalDevice() error = %v, wantErr %v", err, tt.wantErr) return @@ -351,7 +363,7 @@ func Test_pndImplementation_MarshalDevice(t *testing.T) { if got != tt.want { t.Errorf("MarshalDevice() got = %v, want %v", got, tt.want) } - if err := pnd.devices.delete(did); err != nil { + if err := pnd.devices.Delete(did); err != nil { t.Error(err) } }) @@ -359,6 +371,8 @@ func Test_pndImplementation_MarshalDevice(t *testing.T) { } func Test_pndImplementation_RemoveDevice(t *testing.T) { + removeExistingPNDStore() + type args struct { uuid uuid.UUID } @@ -371,11 +385,15 @@ func Test_pndImplementation_RemoveDevice(t *testing.T) { {name: "fails", args: args{uuid: uuid.New()}, wantErr: true}, {name: "fails empty", args: args{uuid: did}, wantErr: true}, } + for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { pnd := newPnd() if tt.name != "fails empty" { - d := &Device{UUID: did} + d := &CommonDevice{ + UUID: did, + sbi: NewSBI(spb.Type_OPENCONFIG), + } if err := pnd.addDevice(d); err != nil { t.Error(err) } @@ -383,7 +401,7 @@ func Test_pndImplementation_RemoveDevice(t *testing.T) { if err := pnd.RemoveDevice(tt.args.uuid); (err != nil) != tt.wantErr { t.Errorf("RemoveDevice() error = %v, wantErr %v", err, tt.wantErr) } - if pnd.devices.exists(did) && tt.name == "default" { + if pnd.devices.Exists(did) && tt.name == "default" { t.Errorf("RemoveDevice() device still in device store %v", pnd.devices) } }) @@ -391,6 +409,11 @@ func Test_pndImplementation_RemoveDevice(t *testing.T) { } func Test_pndImplementation_RemoveSbi(t *testing.T) { + opts := &tpb.TransportOption{ + TransportOption: &tpb.TransportOption_GnmiTransportOption{ + GnmiTransportOption: &tpb.GnmiTransportOption{}, + }, + } type args struct { id uuid.UUID } @@ -402,32 +425,61 @@ func Test_pndImplementation_RemoveSbi(t *testing.T) { {name: "default", args: args{id: defaultSbiID}, wantErr: false}, {name: "fails", args: args{id: uuid.New()}, wantErr: true}, {name: "fails empty", args: args{id: defaultSbiID}, wantErr: true}, + {name: "exclusively remove associated devices", args: args{id: defaultSbiID}, wantErr: false}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { pnd := &pndImplementation{ - name: "test-remove-sbi", - description: "test-remove-sbi", - sbic: sbiStore{store{}}, - devices: deviceStore{store{}}, - id: defaultPndID, + Name: "test-remove-sbi", + Description: "test-remove-sbi", + sbic: store.NewSbiStore(), + devices: store.NewDeviceStore(defaultPndID), + Id: defaultPndID, } - if tt.name != "fails empty" { + if tt.name != "fails empty" && tt.name != "fails" { if err := pnd.addSbi(&OpenConfig{id: defaultSbiID}); err != nil { t.Error(err) } + if err := pnd.AddDevice("associatedDevice", opts, tt.args.id); err != nil { + t.Error(err) + } + if err := pnd.AddDevice("associatedDevice2", opts, tt.args.id); err != nil { + t.Error(err) + } + if tt.name == "exclusively remove associated devices" { + newID := uuid.New() + if err := pnd.addSbi(&OpenConfig{id: newID}); err != nil { + t.Error(err) + } + if err := pnd.AddDevice("associatedDevice2", opts, newID); err != nil { + t.Error(err) + } + } } + if err := pnd.RemoveSbi(tt.args.id); (err != nil) != tt.wantErr { t.Errorf("RemoveSbi() error = %v, wantErr %v", err, tt.wantErr) } - if pnd.sbic.exists(tt.args.id) { - t.Errorf("RemoveDevice() SBI still in SBI store %v", pnd.sbic) + if pnd.sbic.Exists(tt.args.id) { + t.Errorf("RemoveSbi() SBI still in SBI store %v", pnd.sbic) + } + + if tt.name == "exclusively remove associated devices" { + if len(pnd.devices.Store) != 1 { + t.Errorf("RemoveSbi() non associated devices should remain in the storage %v", pnd.devices) + } + } else { + if len(pnd.devices.Store) != 0 { + t.Errorf("RemoveSbi() associated devices have not been removed correctly %v", len(pnd.devices.Store)) + } } }) } } func Test_pndImplementation_Request(t *testing.T) { + removeExistingPNDStore() + type args struct { uuid uuid.UUID path string @@ -457,18 +509,20 @@ func Test_pndImplementation_Request(t *testing.T) { wantErr: true, }, } + for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { deviceWithMockTransport := mockDevice() pnd := newPnd() - tr := deviceWithMockTransport.Transport.(*mocks.Transport) - tr.On("Get", mockContext, mock.Anything).Return(mock.Anything, tt.args.rErr) + tr := deviceWithMockTransport.Transport().(*mocks.Transport) + tr.On("Get", mockContext, mock.Anything).Return(&gpb.GetResponse{}, tt.args.rErr) tr.On("ProcessResponse", mock.Anything, mock.Anything, mock.Anything).Return(tt.args.rErr) - _ = pnd.addDevice(&deviceWithMockTransport) - if err := pnd.Request(tt.args.uuid, tt.args.path); (err != nil) != tt.wantErr { + _ = pnd.addDevice(deviceWithMockTransport) + _, err := pnd.Request(tt.args.uuid, tt.args.path) + if (err != nil) != tt.wantErr { t.Errorf("Request() error = %v, wantErr %v", err, tt.wantErr) } - if err := pnd.devices.delete(mdid); err != nil { + if err := pnd.devices.Delete(mdid); err != nil { t.Error(err) } }) @@ -476,6 +530,8 @@ func Test_pndImplementation_Request(t *testing.T) { } func Test_pndImplementation_RequestAll(t *testing.T) { + removeExistingPNDStore() + type args struct { uuid uuid.UUID path string @@ -505,19 +561,527 @@ func Test_pndImplementation_RequestAll(t *testing.T) { wantErr: true, }, } + for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { deviceWithMockTransport := mockDevice() pnd := newPnd() - tr := deviceWithMockTransport.Transport.(*mocks.Transport) - tr.On("Get", mockContext, mock.Anything).Return(mock.Anything, tt.args.rErr) + tr := deviceWithMockTransport.Transport().(*mocks.Transport) + tr.On("Get", mockContext, mock.Anything).Return(&gpb.GetResponse{}, tt.args.rErr) tr.On("ProcessResponse", mock.Anything, mock.Anything, mock.Anything).Return(tt.args.rErr) - _ = pnd.addDevice(&deviceWithMockTransport) + _ = pnd.addDevice(deviceWithMockTransport) if err := pnd.RequestAll(tt.args.path); (err != nil) != tt.wantErr { t.Errorf("RequestAll() error = %v, wantErr %v", err, tt.wantErr) } - if err := pnd.devices.delete(mdid); err != nil { + if err := pnd.devices.Delete(mdid); err != nil { + t.Error(err) + } + }) + } +} + +func Test_pndImplementation_ChangeOND(t *testing.T) { + opts := &tpb.TransportOption{ + TransportOption: &tpb.TransportOption_GnmiTransportOption{ + GnmiTransportOption: &tpb.GnmiTransportOption{}, + }, + } + type args struct { + operation ppb.ApiOperation + path string + value []string + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "update", + args: args{ + operation: ppb.ApiOperation_UPDATE, + path: "/system/config/hostname", + value: []string{"ceos3000"}, + }, + wantErr: false, + }, + { + name: "replace", + args: args{ + operation: ppb.ApiOperation_REPLACE, + path: "/system/config/hostname", + value: []string{"ceos3000"}, + }, + wantErr: false, + }, + { + name: "delete", + args: args{ + operation: ppb.ApiOperation_DELETE, + path: "/system/config/hostname", + }, + wantErr: false, + }, + { + name: "delete w/args", + args: args{ + operation: ppb.ApiOperation_DELETE, + path: "/system/config/hostname", + value: []string{"ceos3000"}, + }, + wantErr: false, + }, + + // Negative test cases + { + name: "invalid operation", + args: args{ + operation: 54, + }, + wantErr: true, + }, + { + name: "invalid arg count", + args: args{ + operation: ppb.ApiOperation_UPDATE, + path: "/system/config/hostname", + value: []string{"ceos3000", "ceos3001"}, + }, + wantErr: true, + }, + { + name: "invalid arg count - update, no args", + args: args{ + operation: ppb.ApiOperation_UPDATE, + path: "/system/config/hostname", + }, + wantErr: true, + }, + { + name: "invalid arg count - replace, no args", + args: args{ + operation: ppb.ApiOperation_UPDATE, + path: "/system/config/hostname", + }, + wantErr: true, + }, + { + name: "device not found", + args: args{ + operation: ppb.ApiOperation_UPDATE, + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + pnd := newPnd() + if err := pnd.addSbi(&OpenConfig{id: defaultSbiID}); err != nil { + t.Error(err) + } + if err := pnd.AddDevice("testdevice", opts, defaultSbiID); err != nil { + t.Error(err) + return + } + + did, ok := pnd.devices.DeviceNameToUUIDLookup["testdevice"] + if !ok { + err := errors.New("error fetching device") t.Error(err) + return + } + + _, err := pnd.ChangeOND(did, tt.args.operation, tt.args.path, tt.args.value...) + if (err != nil) != tt.wantErr { + t.Errorf("ChangeOND() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !tt.wantErr { + if len(pnd.changes.Store) != 1 { + t.Errorf("ChangeOND() unexpected change count. got %v, want 1", len(pnd.changes.Store)) + } + } + }) + } +} + +func Test_pndImplementation_GetDevice(t *testing.T) { + pnd := newPnd() + sbi := NewSBI(spb.Type_OPENCONFIG) + d, err := NewDevice("", uuid.Nil, newGnmiTransportOptions(), sbi) + if err != nil { + t.Error(err) + return + } + if err = pnd.addDevice(d); err != nil { + t.Error(err) + return + } + type args struct { + uuid uuid.UUID + } + tests := []struct { + name string + args args + want ygot.GoStruct + wantErr bool + }{ + { + name: "default", + args: args{uuid: d.ID()}, + want: sbi.Schema().Root, + wantErr: false, + }, + { + name: "device not found", + args: args{uuid: mdid}, + want: nil, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + foundDevice, err := pnd.GetDevice(tt.args.uuid.String()) + if (err != nil) != tt.wantErr { + t.Errorf("GetDevice() error = %v, wantErr %v", err, tt.wantErr) + return + } + if foundDevice != nil { + if !reflect.DeepEqual(foundDevice.(device.Device).Model(), tt.want) { + t.Errorf("GetDevice() got = %v, want %v", foundDevice.(device.Device).Model(), tt.want) + } + } + }) + } +} + +func Test_pndImplementation_GetDeviceByName(t *testing.T) { + p := newPnd() + sbi := NewSBI(spb.Type_OPENCONFIG) + d, err := NewDevice("my-device", uuid.Nil, newGnmiTransportOptions(), sbi) + if err != nil { + t.Error(err) + return + } + if err = p.addDevice(d); err != nil { + t.Error(err) + return + } + type args struct { + name string + } + tests := []struct { + name string + args args + want ygot.GoStruct + wantErr bool + }{ + { + name: "default", + args: args{name: d.Name()}, + want: sbi.Schema().Root, + wantErr: false, + }, + { + name: "device not found", + args: args{name: "test-device"}, + want: nil, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + foundDevice, err := p.GetDevice(tt.args.name) + if (err != nil) != tt.wantErr { + t.Errorf("GetDeviceByName() error = %v, wantErr %v", err, tt.wantErr) + return + } + if foundDevice != nil { + if !reflect.DeepEqual(foundDevice.(device.Device).Model(), tt.want) { + t.Errorf("GetDeviceByName() got = %v, want %v", foundDevice.(device.Device).Model(), tt.want) + } + } + }) + } +} + +func Test_pndImplementation_Confirm(t *testing.T) { + removeExistingPNDStore() + + tests := []struct { + name string + wantErr bool + }{ + { + name: "default", + wantErr: false, + }, + { + name: "uncommitted", + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + pnd := newPnd() + d := mockDevice() + tr := d.Transport().(*mocks.Transport) + tr.On("Set", mockContext, mock.Anything, mock.Anything).Return(nil) + if err := pnd.addDevice(d); err != nil { + t.Error(err) + return + } + _, err := pnd.ChangeOND(d.ID(), ppb.ApiOperation_UPDATE, "system/config/hostname", "ceos3000") + if err != nil { + t.Error(err) + return + } + u := pnd.PendingChanges()[0] + if tt.name != "uncommitted" { + if err := pnd.Commit(u); (err != nil) != tt.wantErr { + t.Errorf("Confirm() error = %v, wantErr %v", err, tt.wantErr) + return + } + } + if err := pnd.Confirm(u); (err != nil) != tt.wantErr { + t.Errorf("Confirm() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func Test_pndImplementation_PendingChanges(t *testing.T) { + testName := t.Name() + callback := func(first ygot.GoStruct, second ygot.GoStruct) error { + log.Infof("callback in test %v", testName) + return nil + } + + store := store.NewChangeStore() + pending := NewChange(did, &openconfig.Device{}, &openconfig.Device{}, callback) + if err := store.Add(pending); err != nil { + t.Error(err) + return + } + tests := []struct { + name string + want []uuid.UUID + }{ + { + name: "default", + want: []uuid.UUID{pending.cuid}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + pnd := newPnd() + pnd.changes = store + if got := pnd.PendingChanges(); !reflect.DeepEqual(got, tt.want) { + t.Errorf("pndImplementation.PendingChanges() = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_pndImplementation_CommittedChanges(t *testing.T) { + testName := t.Name() + callback := func(first ygot.GoStruct, second ygot.GoStruct) error { + log.Infof("callback in test %v", testName) + return nil + } + + store := store.NewChangeStore() + committed := NewChange(did, &openconfig.Device{}, &openconfig.Device{}, callback) + if err := committed.Commit(); err != nil { + t.Error(err) + return + } + if err := store.Add(committed); err != nil { + t.Error(err) + return + } + tests := []struct { + name string + want []uuid.UUID + }{ + { + name: "default", + want: []uuid.UUID{committed.cuid}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + pnd := newPnd() + pnd.changes = store + if got := pnd.CommittedChanges(); !reflect.DeepEqual(got, tt.want) { + t.Errorf("pndImplementation.CommittedChanges() = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_pndImplementation_ConfirmedChanges(t *testing.T) { + testName := t.Name() + callback := func(first ygot.GoStruct, second ygot.GoStruct) error { + log.Infof("callback in test %v", testName) + return nil + } + store := store.NewChangeStore() + confirmed := NewChange(did, &openconfig.Device{}, &openconfig.Device{}, callback) + if err := confirmed.Commit(); err != nil { + t.Error(err) + return + } + if err := confirmed.Confirm(); err != nil { + t.Error(err) + return + } + if err := store.Add(confirmed); err != nil { + t.Error(err) + return + } + tests := []struct { + name string + want []uuid.UUID + }{ + { + name: "default", + want: []uuid.UUID{confirmed.cuid}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + pnd := newPnd() + pnd.changes = store + if got := pnd.ConfirmedChanges(); !reflect.DeepEqual(got, tt.want) { + t.Errorf("pndImplementation.ConfirmedChanges() = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_pndImplementation_LoadStoredDevices(t *testing.T) { + type args struct { + device interface{} + name string + opts *tpb.TransportOption + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "default", + args: args{ + name: "fridolin", + opts: &tpb.TransportOption{ + TransportOption: &tpb.TransportOption_GnmiTransportOption{ + GnmiTransportOption: &tpb.GnmiTransportOption{}, + }, + }, + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + pnd := newPnd() + if err := pnd.addSbi(&OpenConfig{id: defaultSbiID}); err != nil { + t.Error(err) + } + if tt.name == "already exists" { + pnd.devices.Store[did] = tt.args.device.(device.Device) + } + err := pnd.AddDevice(tt.args.name, tt.args.opts, defaultSbiID) + if (err != nil) != tt.wantErr { + t.Errorf("AddDevice() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + pnd := newPnd() + if err := pnd.addSbi(&OpenConfig{id: defaultSbiID}); err != nil { + t.Error(err) + } + + err := pnd.loadStoredDevices() + if err != nil { + t.Error(err) + } + + dev, err := pnd.GetDevice(tt.args.name) + if err != nil { + t.Errorf("GetDevice() error = %v, want no err", err) + } + + if dev.Name() != tt.args.name { + t.Errorf("Device name is = %s, want %s", dev.Name(), tt.args.name) + } + }) + } +} + +func Test_pndImplementation_AddDeviceWithUUID(t *testing.T) { + type args struct { + uuid uuid.UUID + device interface{} + name string + opts *tpb.TransportOption + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "default", + args: args{ + uuid: did, + name: "fridolin", + opts: &tpb.TransportOption{ + TransportOption: &tpb.TransportOption_GnmiTransportOption{ + GnmiTransportOption: &tpb.GnmiTransportOption{}, + }, + }, + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + pnd := newPnd() + if err := pnd.addSbi(&OpenConfig{id: defaultSbiID}); err != nil { + t.Error(err) + } + if tt.name == "already exists" { + pnd.devices.Store[did] = tt.args.device.(device.Device) + } + + err := pnd.AddDeviceFromStore(tt.args.name, tt.args.uuid, tt.args.opts, defaultSbiID) + if (err != nil) != tt.wantErr { + t.Errorf("AddDevice() error = %v, wantErr %v", err, tt.wantErr) + } + if tt.name != "fails wrong type" { + if err == nil { + d, err := pnd.devices.GetDevice(store.FromString(tt.args.name)) + if err != nil { + t.Errorf("AddDevice() error = %v", err) + return + } + if d.Name() != tt.args.name { + t.Errorf("AddDevice() got = %v, want %v", d.Name(), tt.args.name) + } + if d.ID() != tt.args.uuid { + t.Errorf("AddDevice() got = %v, want %v", d.ID(), tt.args.uuid) + } + if err := pnd.devices.Delete(d.ID()); err != nil { + t.Error(err) + } + } } }) } diff --git a/nucleus/restconf_transport.go b/nucleus/restconf_transport.go index 0dd477196745a83fda3b8460e1c5755b377748a1..06ae108a4332f8e349153cbe79d03b65f55c40f0 100644 --- a/nucleus/restconf_transport.go +++ b/nucleus/restconf_transport.go @@ -2,35 +2,42 @@ package nucleus import ( "context" + + "code.fbi.h-da.de/danet/gosdn/nucleus/errors" + "github.com/openconfig/ygot/ytypes" ) // Restconf implements the Transport interface and provides an SBI with the // possibility to access a Restconf endpoint. -type Restconf struct { -} +type Restconf struct{} -//Get not implemented yet +// Get not yet implemented func (r Restconf) Get(ctx context.Context, params ...string) (interface{}, error) { - return nil, &ErrNotYetImplemented{} + return nil, &errors.ErrNotYetImplemented{} } -//Set not implemented yet -func (r Restconf) Set(ctx context.Context, params ...string) (interface{}, error) { - return nil, &ErrNotYetImplemented{} +// Set not yet implemented +func (r Restconf) Set(ctx context.Context, params ...interface{}) error { + return &errors.ErrNotYetImplemented{} } -// Subscribe not implemented yet +// Subscribe not yet implemented func (r Restconf) Subscribe(ctx context.Context, params ...string) error { - return &ErrNotYetImplemented{} + return &errors.ErrNotYetImplemented{} } -// Type returns the RESTCONF transport type +// Type not yet implemented func (r Restconf) Type() string { return "restconf" } -// ProcessResponse not implemented yet +// GetOptions not yet implemented +func (r Restconf) GetOptions() interface{} { + return &errors.ErrNotYetImplemented{} +} + +// ProcessResponse not yet implemented func (r Restconf) ProcessResponse(resp interface{}, root interface{}, models *ytypes.Schema) error { - return &ErrNotYetImplemented{} + return &errors.ErrNotYetImplemented{} } diff --git a/nucleus/restconf_transport_test.go b/nucleus/restconf_transport_test.go index 5f1eb1e352f2cb8214686c5215eea419c465dcd4..e722632a7e062d3aaacec802611df7861e0fde43 100644 --- a/nucleus/restconf_transport_test.go +++ b/nucleus/restconf_transport_test.go @@ -2,9 +2,10 @@ package nucleus import ( "context" - "github.com/openconfig/ygot/ytypes" "reflect" "testing" + + "github.com/openconfig/ygot/ytypes" ) func TestRestconf_Get(t *testing.T) { @@ -61,26 +62,21 @@ func TestRestconf_ProcessResponse(t *testing.T) { func TestRestconf_Set(t *testing.T) { type args struct { ctx context.Context - params []string + params []interface{} } tests := []struct { name string args args - want interface{} wantErr bool }{ - {name: "not implemented", args: args{}, want: nil, wantErr: true}, + {name: "not implemented", args: args{}, wantErr: true}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { r := Restconf{} - got, err := r.Set(tt.args.ctx, tt.args.params...) + err := r.Set(tt.args.ctx, tt.args.params...) if (err != nil) != tt.wantErr { t.Errorf("Set() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("Set() got = %v, want %v", got, tt.want) } }) } diff --git a/nucleus/sbi-openconfig.go b/nucleus/sbi-openconfig.go deleted file mode 100644 index 0fa4ffa903a1f894325aaf5211341e19a2df754a..0000000000000000000000000000000000000000 --- a/nucleus/sbi-openconfig.go +++ /dev/null @@ -1 +0,0 @@ -package nucleus diff --git a/nucleus/southbound.go b/nucleus/southbound.go index 831e5a92b3a1501ace46fcd3bbdf0fb2eb5ece70..d62411738bac97389cbf9173755c35e53a686b80 100644 --- a/nucleus/southbound.go +++ b/nucleus/southbound.go @@ -1,33 +1,42 @@ package nucleus import ( - "code.fbi.h-da.de/cocsn/yang-models/generated/openconfig" + "code.fbi.h-da.de/danet/gosdn/nucleus/errors" + + spb "code.fbi.h-da.de/danet/api/go/gosdn/southbound" + "code.fbi.h-da.de/danet/gosdn/interfaces/southbound" + + "code.fbi.h-da.de/danet/yang-models/generated/openconfig" "github.com/google/uuid" gpb "github.com/openconfig/gnmi/proto/gnmi" "github.com/openconfig/goyang/pkg/yang" - "github.com/openconfig/ygot/util" "github.com/openconfig/ygot/ygot" "github.com/openconfig/ygot/ytypes" log "github.com/sirupsen/logrus" - "reflect" ) -// SouthboundInterface provides an -// interface for SBI implementations -type SouthboundInterface interface { - // deprecated - SbiIdentifier() string +var csbi *Csbi - // SetNode injects SBI specific model - // representation to the transport. - // Needed for type assertion. - SetNode() func(schema *yang.Entry, root interface{}, path *gpb.Path, val interface{}, opts ...ytypes.SetNodeOpt) error - Schema() *ytypes.Schema - ID() uuid.UUID +func init() { + csbi = &Csbi{id: uuid.New()} } -// Tapi is the implementation of an TAPI SBI. -type Tapi struct { +// NewSBI creates a SouthboundInterface of a given type. +func NewSBI(southbound spb.Type, sbUUID ...uuid.UUID) southbound.SouthboundInterface { + var id uuid.UUID + + if len(sbUUID) == 0 { + id = uuid.New() + } else { + id = sbUUID[0] + } + + switch southbound { + case spb.Type_OPENCONFIG: + return &OpenConfig{id: id} + default: + return nil + } } // OpenConfig is the implementation of an OpenConfig SBI. @@ -55,99 +64,112 @@ func (oc *OpenConfig) Schema() *ytypes.Schema { return schema } -// SetNode injects OpenConfig specific model -// representation to the transport. +// SetNode injects OpenConfig specific model representation to the transport. // Needed for type assertion. -func (oc *OpenConfig) SetNode() func(schema *yang.Entry, root interface{}, path *gpb.Path, val interface{}, opts ...ytypes.SetNodeOpt) error { - return func(schema *yang.Entry, root interface{}, path *gpb.Path, val interface{}, opts ...ytypes.SetNodeOpt) error { - if err := ytypes.SetNode(schema, root.(*openconfig.Device), path, val, opts...); err != nil { - return err - } - return nil - } +func (oc *OpenConfig) SetNode(schema *yang.Entry, root interface{}, path *gpb.Path, val interface{}, opts ...ytypes.SetNodeOpt) error { + return ytypes.SetNode(schema, root.(*openconfig.Device), path, val, opts...) } -// Unmarshal injects OpenConfig specific model -// representation to the transport. +// Unmarshal injects OpenConfig specific model representation to the transport. // Needed for type assertion. -func (oc *OpenConfig) Unmarshal() func([]byte, []string, interface{}, ...ytypes.UnmarshalOpt) error { - return unmarshal +func (oc *OpenConfig) Unmarshal(bytes []byte, path *gpb.Path, goStruct ygot.ValidatedGoStruct, opt ...ytypes.UnmarshalOpt) error { + return unmarshal(oc.Schema(), bytes, path, goStruct, opt...) } -// unmarshal parses a root or 1st level gNMI response to a go struct -// Named return to return appropriate recover error -func unmarshal(bytes []byte, fields []string, goStruct interface{}, opt ...ytypes.UnmarshalOpt) (err error) { +//unmarshal parses a gNMI response to a go struct. +func unmarshal(schema *ytypes.Schema, bytes []byte, path *gpb.Path, goStruct ygot.ValidatedGoStruct, opt ...ytypes.UnmarshalOpt) error { defer func() { if r := recover(); r != nil { - err = r.(error) + log.Error(r.(error)) } }() - switch l := len(fields); l { - case 0: - return openconfig.Unmarshal(bytes, goStruct.(*openconfig.Device), opt...) - case 1: - default: - return &ErrUnsupportedPath{fields} - } - var c ygot.GoStruct - var field string // Load SBI definition - d := openconfig.Device{} - c, field, err = iter(&d, fields) + root, err := ygot.DeepCopy(schema.Root) if err != nil { - return + return err } - if err = openconfig.Unmarshal(bytes, c, opt...); err != nil { - return + validatedDeepCopy, ok := root.(ygot.ValidatedGoStruct) + if !ok { + return &errors.ErrInvalidTypeAssertion{ + Value: root, + Type: (*ygot.ValidatedGoStruct)(nil), + } } - reflect.ValueOf(goStruct.(*openconfig.Device)).Elem().FieldByName(field).Set(reflect.ValueOf(c)) - return nil -} -// iter walks down the provided paths and initializes the ygot.GoStruct. It only works for -// the root level. Named returns to return appropriate recover error -// TODO(mk): Fix deeper layers -func iter(a ygot.GoStruct, fields []string) (b ygot.GoStruct, f string, err error) { - defer func() { - if r := recover(); r != nil { - err = r.(error) - } - }() - var c ygot.GoStruct - var configStruct reflect.Value - f = fields[0] - s := reflect.ValueOf(a).Elem() - h := s.FieldByName(f) - configStruct = reflect.New(h.Type()) - - // Pointer of field needs to be initialized. - // Very convoluted russian doll trick - // https://stackoverflow.com/a/57469950/4378176 - // https://golang.org/src/encoding/json/decode.go?s#L474 - // TODO(mk): Prettify - p2 := configStruct.Elem() - // If we have KeyHelperGoStruct we need make and modify map instead of plain struct - if p2.Kind() == reflect.Map { - p2.Set(reflect.MakeMap(p2.Type())) - configStruct.Elem().Set(p2) - if err := util.InsertIntoMapStructField(a, f, "", p2); err != nil { - panic(err) + // returns the node we want to fill with the data contained in 'bytes', + // using the specified 'path'. + createdNode, _, err := ytypes.GetOrCreateNode(schema.RootSchema(), validatedDeepCopy, path) + if err != nil { + return err + } + validatedCreatedNode, ok := createdNode.(ygot.ValidatedGoStruct) + if !ok { + return &errors.ErrInvalidTypeAssertion{ + Value: createdNode, + Type: (*ygot.ValidatedGoStruct)(nil), } - } else { - configStruct.Elem().Set(reflect.New(p2.Type().Elem())) - b = configStruct.Elem().Interface().(ygot.GoStruct) } - if len(fields) > 1 { - c, _, _ = iter(b, fields[1:]) - } else { - return + + if err := openconfig.Unmarshal(bytes, validatedCreatedNode, opt...); err != nil { + return err } - reflect.ValueOf(b).Elem().FieldByName(f).Set(reflect.ValueOf(c)) - return + + opts := []ygot.MergeOpt{&ygot.MergeOverwriteExistingFields{}} + return ygot.MergeStructInto(goStruct, validatedDeepCopy, opts...) } // ID returns the ID of the OpenConfig SBI func (oc *OpenConfig) ID() uuid.UUID { return oc.id } + +// Type returns the Southbound's type +func (oc *OpenConfig) Type() spb.Type { return spb.Type_OPENCONFIG } + +// Csbi is a stub for the containerised SBI functionality. +// It holds the standard goSDN OPENCONFIG schema for minimum +// compatibility +type Csbi struct { + schema *ytypes.Schema + id uuid.UUID +} + +// SbiIdentifier returns the identifier as a +func (csbi *Csbi) SbiIdentifier() string { + return "csbi" +} + +// SetNode injects schema specific model representation to the transport. +// Needed for type assertion. +func (csbi *Csbi) SetNode(schema *yang.Entry, root interface{}, path *gpb.Path, val interface{}, opts ...ytypes.SetNodeOpt) error { + return ytypes.SetNode(schema, root.(*openconfig.Device), path, val, opts...) +} + +// Unmarshal injects schema specific model representation to the transport. +// Needed for type assertion. +func (csbi *Csbi) Unmarshal(bytes []byte, path *gpb.Path, goStruct ygot.ValidatedGoStruct, opt ...ytypes.UnmarshalOpt) error { + oc := OpenConfig{} + return unmarshal(oc.Schema(), bytes, path, goStruct, opt...) +} + +// Schema is holding the default OpenConfig schema for minimal compatibility +// to gosdn interfaces +func (csbi *Csbi) Schema() *ytypes.Schema { + schema, err := openconfig.Schema() + csbi.schema = schema + if err != nil { + log.Fatal(err) + } + return schema +} + +// ID returns the Southbound's UUID +func (csbi *Csbi) ID() uuid.UUID { + return csbi.id +} + +// Type returns the Southbound's type +func (csbi *Csbi) Type() spb.Type { + return spb.Type_CONTAINERISED +} diff --git a/nucleus/southbound_test.go b/nucleus/southbound_test.go index ab46901446e0cac93464c4aa111436953a51436a..b13f3bb30e1cf672a95f01ceac177978c12d01b1 100644 --- a/nucleus/southbound_test.go +++ b/nucleus/southbound_test.go @@ -1,20 +1,23 @@ package nucleus import ( - "code.fbi.h-da.de/cocsn/gosdn/nucleus/util/proto" - "code.fbi.h-da.de/cocsn/yang-models/generated/openconfig" + "reflect" + "testing" + + spb "code.fbi.h-da.de/danet/api/go/gosdn/southbound" + + "code.fbi.h-da.de/danet/gosdn/nucleus/util/proto" + "code.fbi.h-da.de/danet/yang-models/generated/openconfig" "github.com/google/uuid" gpb "github.com/openconfig/gnmi/proto/gnmi" + "github.com/openconfig/ygot/ygot" "github.com/openconfig/ygot/ytypes" - "reflect" - "testing" ) func TestOpenConfig_Id(t *testing.T) { type fields struct { - transport Transport - schema *ytypes.Schema - id uuid.UUID + schema *ytypes.Schema + id uuid.UUID } tests := []struct { name string @@ -101,7 +104,7 @@ func TestOpenConfig_Schema(t *testing.T) { func Test_unmarshal(t *testing.T) { type args struct { path string - goStruct interface{} + goStruct ygot.ValidatedGoStruct opt []ytypes.UnmarshalOpt } tests := []struct { @@ -110,7 +113,7 @@ func Test_unmarshal(t *testing.T) { wantErr bool }{ { - name: "fail", + name: "interfaces-interface w/o opts", args: args{ goStruct: &openconfig.Device{}, path: "../test/proto/resp-interfaces-interface-arista-ceos", @@ -118,36 +121,36 @@ func Test_unmarshal(t *testing.T) { wantErr: true, }, { - name: "root w/opts", + name: "interfaces w/opts", args: args{ - path: "../test/proto/resp-full-node-arista-ceos", + path: "../test/proto/resp-interfaces-arista-ceos", goStruct: &openconfig.Device{}, opt: []ytypes.UnmarshalOpt{&ytypes.IgnoreExtraFields{}}, }, wantErr: false, }, { - name: "root w/o opts", + name: "interfaces w/o opts", args: args{ - path: "../test/proto/resp-full-node-arista-ceos", + path: "../test/proto/resp-interfaces-arista-ceos", goStruct: &openconfig.Device{}, opt: nil, }, wantErr: true, }, { - name: "interfaces w/opts", + name: "root w/opts", args: args{ - path: "../test/proto/resp-interfaces-arista-ceos", + path: "../test/proto/resp-full-node-arista-ceos", goStruct: &openconfig.Device{}, opt: []ytypes.UnmarshalOpt{&ytypes.IgnoreExtraFields{}}, }, wantErr: false, }, { - name: "interfaces w/o opts", + name: "root w/o opts", args: args{ - path: "../test/proto/resp-interfaces-arista-ceos", + path: "../test/proto/resp-full-node-arista-ceos", goStruct: &openconfig.Device{}, opt: nil, }, @@ -161,10 +164,13 @@ func Test_unmarshal(t *testing.T) { if err != nil { t.Error(err) } - fields := extraxtPathElements(resp.Notification[0].Update[0].Path) bytes := resp.Notification[0].Update[0].Val.GetJsonIetfVal() - if err := unmarshal(bytes, fields, tt.args.goStruct, tt.args.opt...); (err != nil) != tt.wantErr { - t.Errorf("unmarshal() error = %v, wantErr %v", err, tt.wantErr) + oc := NewSBI(spb.Type_OPENCONFIG) + if err := unmarshal(oc.Schema(), bytes, resp.Notification[0].Update[0].Path, tt.args.goStruct, tt.args.opt...); err != nil { + if !tt.wantErr { + t.Errorf("unmarshal() error = %v, wantErr %v", err, tt.wantErr) + } + return } if tt.args.goStruct.(*openconfig.Device).Interfaces == nil && tt.args.opt != nil { t.Errorf("unmarshal() error: field Interfaces must not be nil") @@ -172,3 +178,20 @@ func Test_unmarshal(t *testing.T) { }) } } + +func Test_CreateNewUUID(t *testing.T) { + sbi := NewSBI(spb.Type_OPENCONFIG) + + if sbi.ID().String() == "" { + t.Errorf("sbi.ID().String() is not set.") + } +} + +func Test_UseProvidedUUID(t *testing.T) { + providedSBIId := uuid.New() + sbi := NewSBI(spb.Type_OPENCONFIG, providedSBIId) + + if sbi.ID() != providedSBIId { + t.Errorf("sbi.ID() is not %s. got=%s", providedSBIId.String(), sbi.ID().String()) + } +} diff --git a/nucleus/store.go b/nucleus/store.go deleted file mode 100644 index 0563a5a30533467809380ac25d949bfc4b578e68..0000000000000000000000000000000000000000 --- a/nucleus/store.go +++ /dev/null @@ -1,141 +0,0 @@ -package nucleus - -import ( - "github.com/google/uuid" - log "github.com/sirupsen/logrus" - "reflect" - "sync" -) - -var storeLock sync.RWMutex - -// Storable provides an interface for the controller's storage architecture. -type Storable interface { - ID() uuid.UUID -} - -type store map[uuid.UUID]Storable - -func (s store) exists(id uuid.UUID) bool { - storeLock.RLock() - defer storeLock.RUnlock() - _, ok := s[id] - return ok -} - -func (s store) add(item Storable) error { - if s.exists(item.ID()) { - return &ErrAlreadyExists{item: item} - } - storeLock.Lock() - s[item.ID()] = item - storeLock.Unlock() - log.WithFields(log.Fields{ - "type": reflect.TypeOf(item), - "uuid": item.ID(), - }).Debug("storable was added") - return nil -} - -func (s store) get(id uuid.UUID) (Storable, error) { - if !s.exists(id) { - return nil, &ErrNotFound{id: id} - } - log.WithFields(log.Fields{ - "uuid": id, - }).Debug("storable was accessed") - storeLock.RLock() - defer storeLock.RUnlock() - return s[id], nil -} - -func (s store) delete(id uuid.UUID) error { - if !s.exists(id) { - return &ErrNotFound{id: id} - } - storeLock.Lock() - delete(s, id) - storeLock.Unlock() - log.WithFields(log.Fields{ - "uuid": id, - }).Debug("storable was deleted") - return nil -} - -func (s store) UUIDs() []uuid.UUID { - storeLock.RLock() - defer storeLock.RUnlock() - keys := make([]uuid.UUID, len(s)) - i := 0 - for k := range s { - keys[i] = k - i++ - } - return keys -} - -type sbiStore struct { - store -} - -func (s sbiStore) get(id uuid.UUID) (SouthboundInterface, error) { - item, err := s.store.get(id) - if err != nil { - return nil, err - } - sbi, ok := item.(SouthboundInterface) - if !ok { - return nil, &ErrInvalidTypeAssertion{ - v: sbi, - t: "SouthboundInterface", - } - } - log.WithFields(log.Fields{ - "uuid": id, - }).Debug("southbound interface was accessed") - return sbi, nil -} - -type pndStore struct { - store -} - -func (s pndStore) get(id uuid.UUID) (PrincipalNetworkDomain, error) { - item, err := s.store.get(id) - if err != nil { - return nil, err - } - pnd, ok := item.(PrincipalNetworkDomain) - if !ok { - return nil, &ErrInvalidTypeAssertion{ - v: pnd, - t: "PrincipalNetworkDomain", - } - } - log.WithFields(log.Fields{ - "uuid": id, - }).Debug("principal network domain was accessed") - return pnd, nil -} - -type deviceStore struct { - store -} - -func (s deviceStore) get(id uuid.UUID) (*Device, error) { - item, err := s.store.get(id) - if err != nil { - return nil, err - } - device, ok := item.(*Device) - if !ok { - return nil, &ErrInvalidTypeAssertion{ - v: device, - t: "Device", - } - } - log.WithFields(log.Fields{ - "uuid": id, - }).Debug("device was accessed") - return device, nil -} diff --git a/nucleus/store_test.go b/nucleus/store_test.go deleted file mode 100644 index bc9e2ab00f0e1ac4e31ccc5f616b954da6dc2528..0000000000000000000000000000000000000000 --- a/nucleus/store_test.go +++ /dev/null @@ -1,437 +0,0 @@ -package nucleus - -import ( - "code.fbi.h-da.de/cocsn/gosdn/mocks" - "github.com/google/uuid" - "reflect" - "sort" - "testing" -) - -func Test_store_add(t *testing.T) { - type args struct { - item Storable - } - tests := []struct { - name string - s store - args args - wantErr bool - }{ - { - name: "default", - s: store{}, - args: args{ - item: &mocks.Storable{}, - }, - }, - { - name: "already exists", - s: store{ - iid: &mocks.Storable{}, - }, - args: args{ - item: &mocks.Storable{}, - }, - wantErr: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - tt.args.item.(*mocks.Storable).On("ID").Return(iid) - switch tt.name { - case "already exixts": - _ = tt.s.add(tt.args.item) - default: - } - if err := tt.s.add(tt.args.item); (err != nil) != tt.wantErr { - t.Errorf("add() error = %v, wantErr %v", err, tt.wantErr) - } - }) - } -} - -func Test_store_delete(t *testing.T) { - type args struct { - id uuid.UUID - } - tests := []struct { - name string - s store - args args - wantErr bool - }{ - { - name: "default", - s: store{ - iid: &mocks.Storable{}, - }, - args: args{id: iid}, - wantErr: false, - }, - { - name: "not found empty", - s: store{}, - args: args{id: iid}, - wantErr: true, - }, - { - name: "not found", - s: store{ - iid: &mocks.Storable{}, - }, - args: args{id: altIid}, - wantErr: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if err := tt.s.delete(tt.args.id); (err != nil) != tt.wantErr { - t.Errorf("delete() error = %v, wantErr %v", err, tt.wantErr) - } - if tt.name == "default" { - item, ok := tt.s[iid] - if ok { - t.Errorf("delete() item %v still in store %v", item, tt.s) - } - } - }) - } -} - -func Test_store_exists(t *testing.T) { - type args struct { - id uuid.UUID - } - tests := []struct { - name string - s store - args args - want bool - }{ - { - name: "default", - s: store{ - iid: &mocks.Storable{}, - }, - args: args{id: iid}, - want: true, - }, - { - name: "not found empty", - s: store{}, - args: args{id: iid}, - want: false, - }, - { - name: "not found", - s: store{ - iid: &mocks.Storable{}, - }, - args: args{id: altIid}, - want: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := tt.s.exists(tt.args.id); got != tt.want { - t.Errorf("exists() = %v, want %v", got, tt.want) - } - }) - } -} - -func Test_store_get(t *testing.T) { - type args struct { - id uuid.UUID - } - tests := []struct { - name string - s store - args args - want Storable - wantErr bool - }{ - { - name: "exists", - s: store{ - iid: &mocks.Storable{}, - }, - args: args{id: iid}, - want: &mocks.Storable{}, - wantErr: false, - }, - { - name: "not found", - s: store{ - iid: &mocks.Storable{}, - }, - args: args{id: altIid}, - want: nil, - wantErr: true, - }, - { - name: "not found empty", - s: store{}, - args: args{id: iid}, - want: nil, - wantErr: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := tt.s.get(tt.args.id) - if (err != nil) != tt.wantErr { - t.Errorf("get() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("get() got = %v, want %v", got, tt.want) - } - }) - } -} - -func Test_store_UUIDs(t *testing.T) { - tests := []struct { - name string - s store - want []uuid.UUID - }{ - { - name: "default", - s: store{ - iid: &mocks.Storable{}, - altIid: &mocks.Storable{}, - }, - want: []uuid.UUID{iid, altIid}, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - sort.Slice(tt.want, func(i, j int) bool { - return tt.want[i].String() < tt.want[j].String() - }) - got := tt.s.UUIDs() - sort.Slice(got, func(i, j int) bool { - return got[i].String() < got[j].String() - }) - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("UUIDs() = %v, want %v", got, tt.want) - } - }) - } -} - -func Test_sbiStore_get(t *testing.T) { - type fields struct { - store store - } - type args struct { - id uuid.UUID - } - tests := []struct { - name string - fields fields - args args - want SouthboundInterface - wantErr bool - }{ - { - name: "exists", - fields: fields{ - store: store{ - defaultSbiID: &OpenConfig{id: defaultSbiID}, - }, - }, - args: args{id: defaultSbiID}, - want: &OpenConfig{id: defaultSbiID}, - wantErr: false, - }, - { - name: "fails", - fields: fields{ - store: store{ - defaultSbiID: &OpenConfig{id: defaultSbiID}, - }, - }, - args: args{id: iid}, - wantErr: true, - }, - { - name: "fails empty", - fields: fields{ - store: store{}, - }, - args: args{id: defaultSbiID}, - wantErr: true, - }, - { - name: "fails wrong type", - fields: fields{ - store: store{ - did: &Device{ - UUID: did, - }, - }, - }, - args: args{id: did}, - wantErr: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - s := sbiStore{ - store: tt.fields.store, - } - got, err := s.get(tt.args.id) - if (err != nil) != tt.wantErr { - t.Errorf("get() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("get() got = %v, want %v", got, tt.want) - } - }) - } -} - -func Test_pndStore_get(t *testing.T) { - type fields struct { - store store - } - type args struct { - id uuid.UUID - } - tests := []struct { - name string - fields fields - args args - want PrincipalNetworkDomain - wantErr bool - }{ - { - name: "exists", - fields: fields{ - store: store{ - defaultPndID: &pndImplementation{id: defaultPndID}, - }, - }, - args: args{id: defaultPndID}, - want: &pndImplementation{id: defaultPndID}, - wantErr: false, - }, - { - name: "fails", - fields: fields{ - store: store{ - defaultPndID: &pndImplementation{id: defaultPndID}, - }, - }, - args: args{id: iid}, - wantErr: true, - }, - { - name: "fails empty", - fields: fields{ - store: store{}, - }, - args: args{id: defaultPndID}, - wantErr: true, - }, - { - name: "fails wrong type", - fields: fields{ - store: store{ - did: &Device{ - UUID: did, - }, - }, - }, - args: args{id: did}, - wantErr: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - s := pndStore{ - store: tt.fields.store, - } - got, err := s.get(tt.args.id) - if (err != nil) != tt.wantErr { - t.Errorf("get() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("get() got = %v, want %v", got, tt.want) - } - }) - } -} - -func Test_deviceStore_get(t *testing.T) { - type fields struct { - store store - } - type args struct { - id uuid.UUID - } - tests := []struct { - name string - fields fields - args args - want *Device - wantErr bool - }{ - { - name: "exists", - fields: fields{ - store: store{ - defaultPndID: &Device{UUID: did}}}, - args: args{id: defaultPndID}, - want: &Device{ - UUID: did, - }, - wantErr: false, - }, - { - name: "fails", - fields: fields{ - store: store{ - defaultPndID: &Device{UUID: did}}}, - args: args{id: iid}, - wantErr: true, - }, - { - name: "fails empty", - fields: fields{ - store: store{}, - }, - args: args{id: defaultPndID}, - wantErr: true, - }, - { - name: "fails wrong type", - fields: fields{ - store: store{ - defaultPndID: &pndImplementation{id: defaultPndID}}}, - args: args{id: defaultPndID}, - wantErr: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - s := deviceStore{ - store: tt.fields.store, - } - got, err := s.get(tt.args.id) - if (err != nil) != tt.wantErr { - t.Errorf("get() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("get() got = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/nucleus/transport.go b/nucleus/transport.go index 36dda96300e226ac74de3682d86885e20332191a..49d74e1c2d3795a9b2a987625b756be7b4939ef6 100644 --- a/nucleus/transport.go +++ b/nucleus/transport.go @@ -1,41 +1,38 @@ package nucleus import ( - "bytes" - "context" - "github.com/openconfig/ygot/ytypes" - "io" + tpb "code.fbi.h-da.de/danet/api/go/gosdn/transport" + "code.fbi.h-da.de/danet/gosdn/interfaces/southbound" + "code.fbi.h-da.de/danet/gosdn/interfaces/transport" + "code.fbi.h-da.de/danet/gosdn/nucleus/errors" ) -// Transport provides an interface for -// Transport implementations like RESTCONF -// or gnmi -type Transport interface { - Get(ctx context.Context, params ...string) (interface{}, error) - Set(ctx context.Context, params ...interface{}) (interface{}, error) - Subscribe(ctx context.Context, params ...string) error - Type() string - GetOptions() interface{} - ProcessResponse(resp interface{}, root interface{}, models *ytypes.Schema) error +// NewTransport receives TransportOptions and returns an appropriate Transport +// implementation +func NewTransport(opts *tpb.TransportOption, sbi southbound.SouthboundInterface) (transport.Transport, error) { + if opts == nil { + return nil, &errors.ErrInvalidParameters{ + Func: NewTransport, + Param: "'opt' cannot be 'nil'", + } + } + if sbi == nil { + return nil, errors.ErrInvalidParameters{ + Param: "'sbi' cannot be 'nil'", + } + } + if !validTransportOptions(opts) { + return nil, &errors.ErrInvalidTransportOptions{Opt: opts} + } + switch o := opts.TransportOption.(type) { + case *tpb.TransportOption_GnmiTransportOption: + return newGnmiTransport(opts, sbi) + default: + return nil, &errors.ErrInvalidTransportOptions{Opt: o} + } } -// YANGConsumer is a auxillary type to redirect the response -// of an RESTCONF call to a ygot YANG unmarshaler -type YANGConsumer struct { - Data *bytes.Buffer -} - -// Consume reads the received data into a byte buffer -func (yc YANGConsumer) Consume(reader io.Reader, _ interface{}) error { - _, err := yc.Data.ReadFrom(reader) - return err -} - -// TransportOptions provides an interface for TransportOptions implementations -// for Transports like RESTCONF or gNMI -type TransportOptions interface { - GetAddress() string - GetUsername() string - GetPassword() string - IsTransportOption() +func validTransportOptions(opt *tpb.TransportOption) bool { + return opt.GetGnmiTransportOption() != nil || + opt.GetRestconfTransportOption() != nil } diff --git a/nucleus/transport_test.go b/nucleus/transport_test.go index 0fa4ffa903a1f894325aaf5211341e19a2df754a..4301654adfb3691089c18a90b3472246f8cc843e 100644 --- a/nucleus/transport_test.go +++ b/nucleus/transport_test.go @@ -1 +1,104 @@ package nucleus + +import ( + "testing" + + tpb "code.fbi.h-da.de/danet/api/go/gosdn/transport" + "code.fbi.h-da.de/danet/gosdn/interfaces/southbound" + gpb "github.com/openconfig/gnmi/proto/gnmi" +) + +// TestNewTransport is for input validation only. Functional tests +// are conducted at the transport implementation constructors. +func TestNewTransport(t *testing.T) { + type args struct { + opts *tpb.TransportOption + sbi southbound.SouthboundInterface + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "default", + args: args{ + opts: &tpb.TransportOption{ + Address: "test", + Username: "test", + Password: "test", + Tls: false, + TransportOption: &tpb.TransportOption_GnmiTransportOption{ + GnmiTransportOption: &tpb.GnmiTransportOption{ + Encoding: gpb.Encoding_PROTO, + }, + }, + }, + sbi: &OpenConfig{}, + }, + wantErr: false, + }, + { + name: "no opt", + args: args{ + opts: nil, + sbi: &OpenConfig{}, + }, + wantErr: true, + }, + { + name: "no sbi", + args: args{ + opts: &tpb.TransportOption{ + Address: "test", + Username: "test", + Password: "test", + Tls: false, + TransportOption: &tpb.TransportOption_GnmiTransportOption{ + GnmiTransportOption: &tpb.GnmiTransportOption{ + Encoding: gpb.Encoding_PROTO, + }, + }, + }, + sbi: nil, + }, + wantErr: true, + }, + { + name: "no implementation options", + args: args{ + opts: &tpb.TransportOption{ + Address: "test", + Username: "test", + Password: "test", + Tls: false, + }, + sbi: &OpenConfig{}, + }, + wantErr: true, + }, + { + name: "no inner implementation options", + args: args{ + opts: &tpb.TransportOption{ + Address: "test", + Username: "test", + Password: "test", + Tls: false, + TransportOption: &tpb.TransportOption_GnmiTransportOption{}, + }, + sbi: &OpenConfig{}, + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, err := NewTransport(tt.args.opts, tt.args.sbi) + if (err != nil) != tt.wantErr { + t.Errorf("NewTransport() error = %v, wantErr %v", err, tt.wantErr) + return + } + }) + } +} diff --git a/nucleus/types/types.go b/nucleus/types/types.go new file mode 100644 index 0000000000000000000000000000000000000000..aa514b17b4068fec76f569f0113c9e3a1dd568d1 --- /dev/null +++ b/nucleus/types/types.go @@ -0,0 +1,16 @@ +package types + +// CtxKeyType is a custom type to be used as key in a context.WithValue() or +// context.Value() call. For more information see: +// https://www.calhoun.io/pitfalls-of-context-values-and-how-to-avoid-or-mitigate-them/ +// TODO: Unexport to comply with best practice +type CtxKeyType string + +const ( + // CtxKeyOpts context key for gnmi.SubscribeOptions + CtxKeyOpts CtxKeyType = "opts" + // CtxKeyConfig is a context key for gnmi.Config + CtxKeyConfig = "config" + // CtxKeyOperation is a context key for a gNMI operation (update, replace, delete) + CtxKeyOperation = "op" +) diff --git a/nucleus/util/path/translate.go b/nucleus/util/path/translate.go new file mode 100644 index 0000000000000000000000000000000000000000..94e6a64508832a41954d8739291edcf93744e6c6 --- /dev/null +++ b/nucleus/util/path/translate.go @@ -0,0 +1,16 @@ +package path + +import ( + "strings" + + gpb "github.com/openconfig/gnmi/proto/gnmi" +) + +// ToStrings translates a gNMI path to a slice of strings +func ToStrings(path *gpb.Path) []string { + elems := make([]string, len(path.Elem)) + for i, e := range path.Elem { + elems[i] = strings.Title(e.Name) + } + return elems +} diff --git a/nucleus/util/path/path_traversal.go b/nucleus/util/path/traverse.go similarity index 98% rename from nucleus/util/path/path_traversal.go rename to nucleus/util/path/traverse.go index ada6dbcb1a3439efbcb5b834ec952789e72825e8..403ffc5e441f86013e3eb35a7b6ab331e50b0fb9 100644 --- a/nucleus/util/path/path_traversal.go +++ b/nucleus/util/path/traverse.go @@ -2,10 +2,11 @@ package path import ( "fmt" + "strings" + "github.com/openconfig/goyang/pkg/yang" "github.com/openconfig/ygot/ytypes" log "github.com/sirupsen/logrus" - "strings" ) const delim = "/" @@ -70,7 +71,6 @@ func processEntry(e *yang.Entry) *Element { // Strings constructs a slice containg all possible root to leaf paths. // Calls stringBuilder internally func Strings(paths map[string]*Element) []string { - p := make([]string, 0) ch := make(chan string) stop := make(chan bool) val := make(chan []string) @@ -80,7 +80,8 @@ func Strings(paths map[string]*Element) []string { stringBuilder(ch, &b, v) } stop <- true - p = <-val + p := <-val + return p } @@ -94,7 +95,6 @@ func appendix(c chan string, stop chan bool, pathChan chan []string) { log.Debug(path) case sig = <-stop: log.Debugf("Signal received: %v", sig) - } if sig { break diff --git a/nucleus/util/path/path_traversal_test.go b/nucleus/util/path/traverse_test.go similarity index 99% rename from nucleus/util/path/path_traversal_test.go rename to nucleus/util/path/traverse_test.go index a12455361462f3ceaf606883820580a5d6e39ab9..07ef89d4d31f9b0a1ff487cb9cd934033c609635 100644 --- a/nucleus/util/path/path_traversal_test.go +++ b/nucleus/util/path/traverse_test.go @@ -1,14 +1,15 @@ package path import ( - model "code.fbi.h-da.de/cocsn/gosdn/test/yang" - "github.com/openconfig/goyang/pkg/yang" - "github.com/openconfig/ygot/ytypes" - log "github.com/sirupsen/logrus" "os" "reflect" "sort" "testing" + + model "code.fbi.h-da.de/danet/gosdn/test/yang" + "github.com/openconfig/goyang/pkg/yang" + "github.com/openconfig/ygot/ytypes" + log "github.com/sirupsen/logrus" ) var schema *ytypes.Schema diff --git a/nucleus/util/proto/cap-resp-arista-ceos_test b/nucleus/util/proto/cap-resp-arista-ceos_test deleted file mode 100644 index 009569457324faf59d7bf00bb1915f2f3ccc2ec2..0000000000000000000000000000000000000000 --- a/nucleus/util/proto/cap-resp-arista-ceos_test +++ /dev/null @@ -1,298 +0,0 @@ - -< -arista-exp-eos-vxlan$Arista Networks <http://arista.com/> -B -ietf-netconf2IETF NETCONF (Network Configuration) Working Group -< -arista-rpol-augments$Arista Networks <http://arista.com/> -C -arista-exp-eos-igmpsnooping$Arista Networks <http://arista.com/> -8 -openconfig-vlan-typesOpenConfig working group3.1.0 -? -openconfig-system-managementOpenConfig working group0.3.0 -8 -arista-eos-types$Arista Networks <http://arista.com/> -< -openconfig-openflow-typesOpenConfig working group0.1.2 -7 -openconfig-aaa-typesOpenConfig working group0.4.1 -9 -openconfig-srte-policyOpenConfig working group0.2.1 -9 -openconfig-relay-agentOpenConfig working group0.1.1 -C -openconfig-hercules-qos!OpenConfig Hercules Working Group0.1.0 -1 -openconfig-extensionsOpenConfig working group -/ -arista-mpls-deviationsArista Networks, Inc. -< -arista-vlan-augments$Arista Networks <http://arista.com/> -: -openconfig-platform-cpuOpenConfig working group0.1.1 -< -openconfig-routing-policyOpenConfig working group3.1.1 -= -openconfig-isis-lsdb-typesOpenConfig working group0.4.2 -3 -openconfig-if-ipOpenConfig working group3.0.0 -; -arista-pim-augments$Arista Networks <http://arista.com/> -4 -openconfig-if-poeOpenConfig working group0.1.1 -- -arista-isis-augmentsArista Networks, Inc. -8 -openconfig-ospf-typesOpenConfig working group0.1.3 -/ -arista-intf-deviationsArista Networks, Inc. -5 -openconfig-mpls-srOpenConfig working group3.0.1 -: -openconfig-packet-matchOpenConfig working group1.1.1 -8 -openconfig-inet-typesOpenConfig working group0.3.3 -9 -openconfig-if-ethernetOpenConfig working group2.8.1 -5 -openconfig-pf-srteOpenConfig working group0.2.0 -2 -openconfig-mplsOpenConfig working group3.1.0 -# - -arista-cliArista Networks, Inc. -= -openconfig-system-terminalOpenConfig working group0.3.1 -: -openconfig-platform-psuOpenConfig working group0.2.1 -8 -openconfig-yang-typesOpenConfig working group0.2.1 -8 -openconfig-lldp-typesOpenConfig working group0.1.1 -7 -openconfig-if-tunnelOpenConfig working group0.1.1 -6 -openconfig-messagesOpenConfig working group0.0.1 -B -openconfig-platform-transceiverOpenConfig working group0.7.1 -1 -openconfig-pimOpenConfig working group0.2.0 -@ -openconfig-packet-match-typesOpenConfig working group1.0.2 -C - openconfig-segment-routing-typesOpenConfig working group0.2.0 -: -openconfig-policy-typesOpenConfig working group3.1.1 -/ -arista-lldp-deviationsArista Networks, Inc. -B -openconfig-network-instance-l3OpenConfig working group0.11.1 -E -arista-exp-eos-qos-acl-config$Arista Networks <http://arista.com/> -5 -openconfig-licenseOpenConfig working group0.2.0 -: -openconfig-platform-fanOpenConfig working group0.1.1 -/ -arista-system-augmentsArista Networks, Inc. -2 -openconfig-isisOpenConfig working group0.6.0 -H -/arista-network-instance-notsupported-deviationsArista Networks, Inc. -B -)arista-interfaces-notsupported-deviationsArista Networks, Inc. -< -arista-mpls-augments$Arista Networks <http://arista.com/> -3 -arista-openflow-deviationsArista Networks, Inc. -7 -openconfig-platformOpenConfig working group0.12.2 -D -arista-exp-eos-varp-net-inst$Arista Networks <http://arista.com/> -9 -openconfig-ospf-policyOpenConfig working group0.1.3 -6 -openconfig-if-typesOpenConfig working group0.2.1 -: -arista-exp-eos-qos$Arista Networks <http://arista.com/> -2 -openconfig-igmpOpenConfig working group0.2.0 -) -arista-gnoi-certArista Networks, Inc. -/ -arista-isis-deviationsArista Networks, Inc. -4 -openconfig-systemOpenConfig working group0.9.1 -> -arista-vlan-deviations$Arista Networks <http://arista.com/> -# -vlan-translationArista Networks -; -openconfig-local-routingOpenConfig working group1.1.0 -@ -arista-exp-eos-varp-intf$Arista Networks <http://arista.com/> -; -arista-exp-eos-mlag$Arista Networks <http://arista.com/> -8 -openconfig-igmp-typesOpenConfig working group0.1.1 -1 -openconfig-aftOpenConfig working group0.4.1 -- -arista-srte-augmentsArista Networks, Inc. -E -arista-relay-agent-deviations$Arista Networks <http://arista.com/> -7 -openconfig-mpls-rsvpOpenConfig working group3.0.2 -1 -openconfig-aaaOpenConfig working group0.4.3 -6 -arista-exp-eos$Arista Networks <http://arista.com/> -H -openconfig-hercules-platform!OpenConfig Hercules Working Group0.2.0 -. -arista-acl-deviationsArista Networks, Inc. -/ -arista-lacp-deviationsArista Networks, Inc. -? -ietf-interfaces,IETF NETMOD (Network Modeling) Working Group -. -arista-bgp-deviationsArista Networks, Inc. -< -openconfig-platform-typesOpenConfig working group1.0.0 -; -"arista-acl-notsupported-deviationsArista Networks, Inc. -3 -openconfig-typesOpenConfig working group0.6.0 -M -ietf-yang-types:IETF NETMOD (NETCONF Data Modeling Language) Working Group -1 -openconfig-qosOpenConfig working group0.2.3 -. -arista-bfd-deviationsArista Networks, Inc. -@ -'arista-messages-notsupported-deviationsArista Networks, Inc. -9 -openconfig-alarm-typesOpenConfig working group0.2.1 -< -#arista-exp-eos-l2protocolforwardingArista Networks, Inc. -6 -openconfig-openflowOpenConfig working group0.1.2 -> -%arista-system-notsupported-deviationsArista Networks, Inc. -7 -openconfig-pim-typesOpenConfig working group0.1.1 -2 -openconfig-vlanOpenConfig working group3.2.0 -F --arista-routing-policy-notsupported-deviationsArista Networks, Inc. -7 -openconfig-aft-typesOpenConfig Working Group0.3.4 -, -arista-aft-augmentsArista Networks, Inc. -< -arista-lacp-augments$Arista Networks <http://arista.com/> -1 -openconfig-bfdOpenConfig working group0.2.1 -< -openconfig-system-loggingOpenConfig working group0.3.1 -4 -openconfig-alarmsOpenConfig working group0.3.2 -8 -openconfig-isis-typesOpenConfig working group0.4.2 -? -openconfig-platform-linecardOpenConfig working group0.1.2 -< -#arista-lldp-notsupported-deviationsArista Networks, Inc. -, -arista-exp-eos-evpnArista Networks, Inc. -5 -openconfig-rib-bgpOpenConfig working group0.7.0 -@ -'arista-platform-notsupported-deviationsArista Networks, Inc. -@ -arista-exp-eos-multicast$Arista Networks <http://arista.com/> -; -"arista-bfd-notsupported-deviationsArista Networks, Inc. -? -openconfig-policy-forwardingOpenConfig working group0.2.1 -2 -openconfig-lacpOpenConfig working group1.1.1 -- -arista-lldp-augmentsArista Networks, Inc. -; -arista-bfd-augments$Arista Networks <http://arista.com/> -1 -openconfig-bgpOpenConfig working group6.0.0 - -iana-if-typeIANA -/ -arista-rpol-deviationsArista Networks, Inc. -; -openconfig-rib-bgp-typesOpenConfig working group0.5.0 -M -ietf-inet-types:IETF NETMOD (NETCONF Data Modeling Language) Working Group -8 -openconfig-bgp-policyOpenConfig working group6.0.1 -< -arista-intf-augments$Arista Networks <http://arista.com/> -8 -arista-local-routing-deviationsArista Networks, Inc. -8 -openconfig-interfacesOpenConfig working group2.4.3 -: -openconfig-if-aggregateOpenConfig working group2.4.3 -/ -arista-srte-deviationsArista Networks, Inc. -A -arista-exp-eos-qos-config$Arista Networks <http://arista.com/> -2 -openconfig-lldpOpenConfig working group0.2.1 -J -openconfig-hercules-interfaces!OpenConfig Hercules Working Group0.2.0 -6 -openconfig-mpls-ldpOpenConfig working group3.0.2 -8 -openconfig-mpls-typesOpenConfig working group3.2.0 -M -ietf-netconf-monitoring2IETF NETCONF (Network Configuration) Working Group -7 -openconfig-bgp-typesOpenConfig working group5.2.0 -< -#arista-lacp-notsupported-deviationsArista Networks, Inc. -E -,arista-local-routing-notsupported-deviationsArista Networks, Inc. -, -arista-bgp-augmentsArista Networks, Inc. -2 -arista-netinst-deviationsArista Networks, Inc. -; -"arista-bgp-notsupported-deviationsArista Networks, Inc. -D -!openconfig-network-instance-typesOpenConfig working group0.8.2 -1 -openconfig-aclOpenConfig working group1.1.1 -7 -openconfig-qos-typesOpenConfig working group0.2.1 -5 -openconfig-procmonOpenConfig working group0.4.0 -, -arista-qos-augmentsArista Networks, Inc. -; -openconfig-platform-portOpenConfig working group0.3.3 -4 -openconfig-ospfv2OpenConfig working group0.2.2 -1 -arista-system-deviationsArista Networks, Inc. -> -openconfig-transport-typesOpenConfig working group0.11.0 -? -openconfig-network-instanceOpenConfig working group0.14.0 -+ -arista-rpc-netconfArista Networks, Inc. -= -openconfig-segment-routingOpenConfig working group0.3.0 -; -"arista-qos-notsupported-deviationsArista Networks, Inc. -C -arista-exp-eos-vxlan-config$Arista Networks <http://arista.com/>�0.7.0 \ No newline at end of file diff --git a/nucleus/util/proto/message.go b/nucleus/util/proto/message.go index 816c728e1948967130fe82aa9397ea798fb2da44..066c0434e96fab416ffd4511e7101fdd31208165 100644 --- a/nucleus/util/proto/message.go +++ b/nucleus/util/proto/message.go @@ -2,8 +2,9 @@ package proto import ( "fmt" - "google.golang.org/protobuf/proto" "io/ioutil" + + "google.golang.org/protobuf/proto" ) /* diff --git a/nucleus/util/proto/message_test.go b/nucleus/util/proto/message_test.go index 3f756d3aef8ad5c467a2572d793e374bb2802c30..dfa6e5587bb42a912c64f316578feeaf84daaf8e 100644 --- a/nucleus/util/proto/message_test.go +++ b/nucleus/util/proto/message_test.go @@ -1,12 +1,13 @@ package proto import ( - gpb "github.com/openconfig/gnmi/proto/gnmi" - pb "google.golang.org/protobuf/proto" "os" "reflect" "strings" "testing" + + gpb "github.com/openconfig/gnmi/proto/gnmi" + pb "google.golang.org/protobuf/proto" ) func TestMain(m *testing.M) { diff --git a/nucleus/util/proto/req-full-node-arista-ceos_test b/nucleus/util/proto/req-full-node-arista-ceos_test deleted file mode 100644 index 6223295e2984b8002ea5573e8fbbecb77ba9dc6d..0000000000000000000000000000000000000000 Binary files a/nucleus/util/proto/req-full-node-arista-ceos_test and /dev/null differ diff --git a/nucleus/util/proto/req-full-node_test b/nucleus/util/proto/req-full-node_test deleted file mode 100644 index 087f7d8275a07a95d6809081bab6ccecfa81a9f1..0000000000000000000000000000000000000000 --- a/nucleus/util/proto/req-full-node_test +++ /dev/null @@ -1,7 +0,0 @@ -2 - -interfaces - interface - -interfaces - interface( \ No newline at end of file diff --git a/nucleus/util/proto/req-interfaces-arista-ceos_test b/nucleus/util/proto/req-interfaces-arista-ceos_test deleted file mode 100644 index e444e33aa6d44fc9ca4538f5a030df6c8d88a708..0000000000000000000000000000000000000000 --- a/nucleus/util/proto/req-interfaces-arista-ceos_test +++ /dev/null @@ -1,5 +0,0 @@ - - -interfaces - -interfaces( \ No newline at end of file diff --git a/nucleus/util/proto/req-interfaces-interface-arista-ceos_test b/nucleus/util/proto/req-interfaces-interface-arista-ceos_test deleted file mode 100644 index 087f7d8275a07a95d6809081bab6ccecfa81a9f1..0000000000000000000000000000000000000000 --- a/nucleus/util/proto/req-interfaces-interface-arista-ceos_test +++ /dev/null @@ -1,7 +0,0 @@ -2 - -interfaces - interface - -interfaces - interface( \ No newline at end of file diff --git a/nucleus/util/proto/req-interfaces-wildcard_test b/nucleus/util/proto/req-interfaces-wildcard_test deleted file mode 100644 index bd113697d2f21f1dbd7a3a881c6ab70cd4ec4644..0000000000000000000000000000000000000000 --- a/nucleus/util/proto/req-interfaces-wildcard_test +++ /dev/null @@ -1,12 +0,0 @@ -c - -interfaces -interface[name=*] -state -name - -interfaces - interface -name* -state -name( \ No newline at end of file diff --git a/nucleus/util/proto/resp-full-node-arista-ceos_test b/nucleus/util/proto/resp-full-node-arista-ceos_test deleted file mode 100644 index 9bcd16e666a683a570c5141eb01b4ed16ad52b8b..0000000000000000000000000000000000000000 Binary files a/nucleus/util/proto/resp-full-node-arista-ceos_test and /dev/null differ diff --git a/nucleus/util/proto/resp-full-node_test b/nucleus/util/proto/resp-full-node_test deleted file mode 100644 index 4614be84e811d8a96624192f082c97ec9edf76be..0000000000000000000000000000000000000000 --- a/nucleus/util/proto/resp-full-node_test +++ /dev/null @@ -1,7 +0,0 @@ - -�""�" -0 - -interfaces - interface -nameEthernet510�"Z�"{"openconfig-interfaces:config":{"description":"","enabled":true,"arista-intf-augments:load-interval":300,"loopback-mode":false,"mtu":0,"name":"Ethernet510","openconfig-vlan:tpid":"openconfig-vlan-types:TPID_0X8100","type":"iana-if-type:ethernetCsmacd"},"openconfig-if-ethernet:ethernet":{"config":{"arista-intf-augments:fec-encoding":{"disabled":false,"fire-code":false,"reed-solomon":false,"reed-solomon544":false},"openconfig-hercules-interfaces:forwarding-viable":true,"mac-address":"00:00:00:00:00:00","port-speed":"SPEED_UNKNOWN","arista-intf-augments:sfp-1000base-t":false},"arista-intf-augments:pfc":{"priorities":{"priority":[{"index":0,"state":{"in-frames":"0","index":0,"out-frames":"0"}},{"index":1,"state":{"in-frames":"0","index":1,"out-frames":"0"}},{"index":2,"state":{"in-frames":"0","index":2,"out-frames":"0"}},{"index":3,"state":{"in-frames":"0","index":3,"out-frames":"0"}},{"index":4,"state":{"in-frames":"0","index":4,"out-frames":"0"}},{"index":5,"state":{"in-frames":"0","index":5,"out-frames":"0"}},{"index":6,"state":{"in-frames":"0","index":6,"out-frames":"0"}},{"index":7,"state":{"in-frames":"0","index":7,"out-frames":"0"}}]}},"state":{"auto-negotiate":false,"counters":{"in-crc-errors":"0","in-fragment-frames":"0","in-jabber-frames":"0","in-mac-control-frames":"0","in-mac-pause-frames":"0","in-oversize-frames":"0","out-mac-control-frames":"0","out-mac-pause-frames":"0"},"duplex-mode":"FULL","enable-flow-control":false,"openconfig-hercules-interfaces:forwarding-viable":true,"hw-mac-address":"02:42:c0:a8:02:41","mac-address":"02:42:c0:a8:02:41","negotiated-port-speed":"SPEED_UNKNOWN","port-speed":"SPEED_UNKNOWN","arista-intf-augments:supported-speeds":["SPEED_5GB","SPEED_25GB","SPEED_50GB","SPEED_100GB","SPEED_10MB","SPEED_100GB_2LANE","SPEED_100MB","SPEED_1GB","SPEED_2500MB","SPEED_400GB","SPEED_10GB","SPEED_40GB","SPEED_200GB_4LANE","SPEED_200GB_8LANE","SPEED_50GB_1LANE"]}},"openconfig-interfaces:hold-time":{"config":{"down":0,"up":0},"state":{"down":0,"up":0}},"openconfig-interfaces:name":"Ethernet510","openconfig-interfaces:state":{"admin-status":"UP","counters":{"in-broadcast-pkts":"294224","in-discards":"0","in-errors":"0","in-fcs-errors":"0","in-multicast-pkts":"1412","in-octets":"72226989","in-unicast-pkts":"642","out-broadcast-pkts":"0","out-discards":"0","out-errors":"0","out-multicast-pkts":"0","out-octets":"0","out-unicast-pkts":"0"},"description":"","enabled":true,"openconfig-platform-port:hardware-port":"Port510","ifindex":510,"arista-intf-augments:inactive":false,"last-change":"1612959137249521152","loopback-mode":false,"mtu":0,"name":"Ethernet510","oper-status":"UP","openconfig-vlan:tpid":"openconfig-vlan-types:TPID_0X8100","type":"iana-if-type:ethernetCsmacd"},"openconfig-interfaces:subinterfaces":{"subinterface":[{"config":{"description":"","enabled":true,"index":0},"index":0,"openconfig-if-ip:ipv4":{"config":{"dhcp-client":false,"enabled":true,"mtu":1500},"state":{"dhcp-client":false,"enabled":true,"mtu":1500},"unnumbered":{"config":{"enabled":false},"state":{"enabled":false}}},"openconfig-if-ip:ipv6":{"addresses":{"address":[{"config":{"ip":"fdfd::ce05","prefix-length":64},"ip":"fdfd::ce05","state":{"ip":"fdfd::ce05","origin":"STATIC","prefix-length":64,"status":"PREFERRED"}}]},"config":{"dhcp-client":false,"enabled":false,"mtu":1500},"neighbors":{"neighbor":[{"config":{"ip":"fdfd::1"},"ip":"fdfd::1","state":{"ip":"fdfd::1","link-layer-address":"74:83:c2:fe:86:ad","neighbor-state":"REACHABLE","origin":"DYNAMIC"}},{"config":{"ip":"fe80::7683:c2ff:fefe:86ad"},"ip":"fe80::7683:c2ff:fefe:86ad","state":{"ip":"fe80::7683:c2ff:fefe:86ad","link-layer-address":"74:83:c2:fe:86:ad","neighbor-state":"REACHABLE","origin":"DYNAMIC"}},{"config":{"ip":"fe80::c3:43ff:fec5:da0b"},"ip":"fe80::c3:43ff:fec5:da0b","state":{"ip":"fe80::c3:43ff:fec5:da0b","link-layer-address":"02:c3:43:c5:da:0b","neighbor-state":"REACHABLE","origin":"DYNAMIC"}},{"config":{"ip":"fdfd::28"},"ip":"fdfd::28","state":{"ip":"fdfd::28","link-layer-address":"02:c3:43:c5:da:0b","neighbor-state":"REACHABLE","origin":"DYNAMIC"}},{"config":{"ip":"fe80::1"},"ip":"fe80::1","state":{"ip":"fe80::1","link-layer-address":"74:83:c2:fe:86:ad","neighbor-state":"REACHABLE","origin":"DYNAMIC"}}]},"state":{"dhcp-client":false,"enabled":false,"mtu":1500}},"state":{"counters":{"in-fcs-errors":"0"},"description":"","enabled":true,"index":0}}]}} \ No newline at end of file diff --git a/nucleus/util/proto/resp-interfaces-arista-ceos_test b/nucleus/util/proto/resp-interfaces-arista-ceos_test deleted file mode 100644 index 58e139172f4264b079f1f61ec7f27fe454129734..0000000000000000000000000000000000000000 --- a/nucleus/util/proto/resp-interfaces-arista-ceos_test +++ /dev/null @@ -1,5 +0,0 @@ - -�"� - - -interfaces�Z�{"openconfig-interfaces:interface":[{"config":{"description":"","enabled":true,"arista-intf-augments:load-interval":300,"loopback-mode":false,"mtu":0,"name":"Ethernet510","openconfig-vlan:tpid":"openconfig-vlan-types:TPID_0X8100","type":"iana-if-type:ethernetCsmacd"},"openconfig-if-ethernet:ethernet":{"config":{"arista-intf-augments:fec-encoding":{"disabled":false,"fire-code":false,"reed-solomon":false,"reed-solomon544":false},"openconfig-hercules-interfaces:forwarding-viable":true,"mac-address":"00:00:00:00:00:00","port-speed":"SPEED_UNKNOWN","arista-intf-augments:sfp-1000base-t":false},"arista-intf-augments:pfc":{"priorities":{"priority":[{"index":0,"state":{"in-frames":"0","index":0,"out-frames":"0"}},{"index":1,"state":{"in-frames":"0","index":1,"out-frames":"0"}},{"index":2,"state":{"in-frames":"0","index":2,"out-frames":"0"}},{"index":3,"state":{"in-frames":"0","index":3,"out-frames":"0"}},{"index":4,"state":{"in-frames":"0","index":4,"out-frames":"0"}},{"index":5,"state":{"in-frames":"0","index":5,"out-frames":"0"}},{"index":6,"state":{"in-frames":"0","index":6,"out-frames":"0"}},{"index":7,"state":{"in-frames":"0","index":7,"out-frames":"0"}}]}},"state":{"auto-negotiate":false,"counters":{"in-crc-errors":"0","in-fragment-frames":"0","in-jabber-frames":"0","in-mac-control-frames":"0","in-mac-pause-frames":"0","in-oversize-frames":"0","out-mac-control-frames":"0","out-mac-pause-frames":"0"},"duplex-mode":"FULL","enable-flow-control":false,"openconfig-hercules-interfaces:forwarding-viable":true,"hw-mac-address":"02:42:c0:a8:02:42","mac-address":"02:42:c0:a8:02:42","negotiated-port-speed":"SPEED_UNKNOWN","port-speed":"SPEED_UNKNOWN","arista-intf-augments:supported-speeds":["SPEED_200GB_8LANE","SPEED_100MB","SPEED_1GB","SPEED_10GB","SPEED_400GB","SPEED_40GB","SPEED_2500MB","SPEED_50GB","SPEED_50GB_1LANE","SPEED_25GB","SPEED_100GB","SPEED_100GB_2LANE","SPEED_10MB","SPEED_200GB_4LANE","SPEED_5GB"]}},"hold-time":{"config":{"down":0,"up":0},"state":{"down":0,"up":0}},"name":"Ethernet510","state":{"admin-status":"UP","counters":{"in-broadcast-pkts":"344691","in-discards":"0","in-errors":"0","in-fcs-errors":"0","in-multicast-pkts":"1","in-octets":"93260151","in-unicast-pkts":"0","out-broadcast-pkts":"0","out-discards":"0","out-errors":"0","out-multicast-pkts":"0","out-octets":"0","out-unicast-pkts":"0"},"description":"","enabled":true,"openconfig-platform-port:hardware-port":"Port510","ifindex":510,"arista-intf-augments:inactive":false,"last-change":"1614091948142304000","loopback-mode":false,"mtu":0,"name":"Ethernet510","oper-status":"UP","openconfig-vlan:tpid":"openconfig-vlan-types:TPID_0X8100","type":"iana-if-type:ethernetCsmacd"},"subinterfaces":{"subinterface":[{"config":{"description":"","enabled":true,"index":0},"index":0,"openconfig-if-ip:ipv4":{"config":{"dhcp-client":false,"enabled":false,"mtu":1500},"state":{"dhcp-client":false,"enabled":false,"mtu":1500},"unnumbered":{"config":{"enabled":false},"state":{"enabled":false}}},"openconfig-if-ip:ipv6":{"config":{"dhcp-client":false,"enabled":false,"mtu":1500},"state":{"dhcp-client":false,"enabled":false,"mtu":1500}},"state":{"counters":{"in-fcs-errors":"0"},"description":"","enabled":true,"index":0}}]}}]} \ No newline at end of file diff --git a/nucleus/util/proto/resp-interfaces-interface-arista-ceos_test b/nucleus/util/proto/resp-interfaces-interface-arista-ceos_test deleted file mode 100644 index 05f0804b1153e5982ff5d5e4d4a32d9d6d6be7d0..0000000000000000000000000000000000000000 --- a/nucleus/util/proto/resp-interfaces-interface-arista-ceos_test +++ /dev/null @@ -1,7 +0,0 @@ - -�"� -0 - -interfaces - interface -nameEthernet510�Z�{"openconfig-interfaces:config":{"description":"","enabled":true,"arista-intf-augments:load-interval":300,"loopback-mode":false,"mtu":0,"name":"Ethernet510","openconfig-vlan:tpid":"openconfig-vlan-types:TPID_0X8100","type":"iana-if-type:ethernetCsmacd"},"openconfig-if-ethernet:ethernet":{"config":{"arista-intf-augments:fec-encoding":{"disabled":false,"fire-code":false,"reed-solomon":false,"reed-solomon544":false},"openconfig-hercules-interfaces:forwarding-viable":true,"mac-address":"00:00:00:00:00:00","port-speed":"SPEED_UNKNOWN","arista-intf-augments:sfp-1000base-t":false},"arista-intf-augments:pfc":{"priorities":{"priority":[{"index":0,"state":{"in-frames":"0","index":0,"out-frames":"0"}},{"index":1,"state":{"in-frames":"0","index":1,"out-frames":"0"}},{"index":2,"state":{"in-frames":"0","index":2,"out-frames":"0"}},{"index":3,"state":{"in-frames":"0","index":3,"out-frames":"0"}},{"index":4,"state":{"in-frames":"0","index":4,"out-frames":"0"}},{"index":5,"state":{"in-frames":"0","index":5,"out-frames":"0"}},{"index":6,"state":{"in-frames":"0","index":6,"out-frames":"0"}},{"index":7,"state":{"in-frames":"0","index":7,"out-frames":"0"}}]}},"state":{"auto-negotiate":false,"counters":{"in-crc-errors":"0","in-fragment-frames":"0","in-jabber-frames":"0","in-mac-control-frames":"0","in-mac-pause-frames":"0","in-oversize-frames":"0","out-mac-control-frames":"0","out-mac-pause-frames":"0"},"duplex-mode":"FULL","enable-flow-control":false,"openconfig-hercules-interfaces:forwarding-viable":true,"hw-mac-address":"02:42:c0:a8:02:42","mac-address":"02:42:c0:a8:02:42","negotiated-port-speed":"SPEED_UNKNOWN","port-speed":"SPEED_UNKNOWN","arista-intf-augments:supported-speeds":["SPEED_200GB_8LANE","SPEED_100MB","SPEED_1GB","SPEED_10GB","SPEED_400GB","SPEED_40GB","SPEED_2500MB","SPEED_50GB","SPEED_50GB_1LANE","SPEED_25GB","SPEED_100GB","SPEED_100GB_2LANE","SPEED_10MB","SPEED_200GB_4LANE","SPEED_5GB"]}},"openconfig-interfaces:hold-time":{"config":{"down":0,"up":0},"state":{"down":0,"up":0}},"openconfig-interfaces:name":"Ethernet510","openconfig-interfaces:state":{"admin-status":"UP","counters":{"in-broadcast-pkts":"344691","in-discards":"0","in-errors":"0","in-fcs-errors":"0","in-multicast-pkts":"1","in-octets":"93260151","in-unicast-pkts":"0","out-broadcast-pkts":"0","out-discards":"0","out-errors":"0","out-multicast-pkts":"0","out-octets":"0","out-unicast-pkts":"0"},"description":"","enabled":true,"openconfig-platform-port:hardware-port":"Port510","ifindex":510,"arista-intf-augments:inactive":false,"last-change":"1614091948142304000","loopback-mode":false,"mtu":0,"name":"Ethernet510","oper-status":"UP","openconfig-vlan:tpid":"openconfig-vlan-types:TPID_0X8100","type":"iana-if-type:ethernetCsmacd"},"openconfig-interfaces:subinterfaces":{"subinterface":[{"config":{"description":"","enabled":true,"index":0},"index":0,"openconfig-if-ip:ipv4":{"config":{"dhcp-client":false,"enabled":false,"mtu":1500},"state":{"dhcp-client":false,"enabled":false,"mtu":1500},"unnumbered":{"config":{"enabled":false},"state":{"enabled":false}}},"openconfig-if-ip:ipv6":{"config":{"dhcp-client":false,"enabled":false,"mtu":1500},"state":{"dhcp-client":false,"enabled":false,"mtu":1500}},"state":{"counters":{"in-fcs-errors":"0"},"description":"","enabled":true,"index":0}}]}} \ No newline at end of file diff --git a/nucleus/util/proto/resp-interfaces-wildcard_test b/nucleus/util/proto/resp-interfaces-wildcard_test deleted file mode 100644 index 50cb9f4c7021af0340d92cde6f1320ffb066e68d..0000000000000000000000000000000000000000 --- a/nucleus/util/proto/resp-interfaces-wildcard_test +++ /dev/null @@ -1,10 +0,0 @@ - -T"R -A - -interfaces - interface -nameEthernet510 -state -name -Ethernet510 \ No newline at end of file diff --git a/nucleus/util/proto/resp-set-system-config-hostname_test b/nucleus/util/proto/resp-set-system-config-hostname_test deleted file mode 100644 index c656ee5bb56b47d1e306627823c577d1b51d6988..0000000000000000000000000000000000000000 --- a/nucleus/util/proto/resp-set-system-config-hostname_test +++ /dev/null @@ -1,8 +0,0 @@ ->: -system -config -hostname -system -config - -hostname �����ȶ \ No newline at end of file diff --git a/store/changeStores.go b/store/changeStores.go new file mode 100644 index 0000000000000000000000000000000000000000..ef2d5a75002d14399c3e00c5acca0912798dc88f --- /dev/null +++ b/store/changeStores.go @@ -0,0 +1,68 @@ +package store + +import ( + "code.fbi.h-da.de/danet/gosdn/interfaces/change" + "code.fbi.h-da.de/danet/gosdn/nucleus/errors" + "github.com/google/uuid" + log "github.com/sirupsen/logrus" + + ppb "code.fbi.h-da.de/danet/api/go/gosdn/pnd" +) + +// ChangeStore is used to store Changes +type ChangeStore struct { + *genericStore +} + +// NewChangeStore returns a ChangeStore +func NewChangeStore() *ChangeStore { + return &ChangeStore{genericStore: newGenericStore()} +} + +// GetChange takes a Change's UUID and returns the Change. If the requested +// Change does not exist an error is returned. +func (s *ChangeStore) GetChange(id uuid.UUID) (change.Change, error) { + item, err := s.genericStore.Get(id) + if err != nil { + return nil, err + } + c, ok := item.(change.Change) + if !ok { + return nil, &errors.ErrInvalidTypeAssertion{ + Value: c, + Type: (*change.Change)(nil), + } + } + log.WithFields(log.Fields{ + "uuid": id, + }).Debug("change was accessed") + return c, nil +} + +// Pending returns the UUIDs of all pending changes +func (s *ChangeStore) Pending() []uuid.UUID { + return filterChanges(s, ppb.Change_PENDING) +} + +// Committed returns the UUIDs of all pending changes +func (s *ChangeStore) Committed() []uuid.UUID { + return filterChanges(s, ppb.Change_COMMITTED) +} + +// Confirmed returns the UUIDs of all pending changes +func (s *ChangeStore) Confirmed() []uuid.UUID { + return filterChanges(s, ppb.Change_CONFIRMED) +} + +func filterChanges(store *ChangeStore, state ppb.Change_State) []uuid.UUID { + changes := make([]uuid.UUID, 0) + for _, ch := range store.Store { + switch c := ch.(type) { + case change.Change: + if c.State() == state { + changes = append(changes, c.ID()) + } + } + } + return changes +} diff --git a/store/change_store_test.go b/store/change_store_test.go new file mode 100644 index 0000000000000000000000000000000000000000..fee6c99bd07c75114c41eac9648ef77396dc6256 --- /dev/null +++ b/store/change_store_test.go @@ -0,0 +1,226 @@ +package store + +import ( + "log" + "reflect" + "testing" + + "code.fbi.h-da.de/danet/api/go/gosdn/pnd" + ppb "code.fbi.h-da.de/danet/api/go/gosdn/pnd" + "code.fbi.h-da.de/danet/gosdn/mocks" + "github.com/google/uuid" +) + +func TestChangeStore_Pending(t *testing.T) { + changeMock := &mocks.Change{} + changeMock.On("ID").Return(cuid) + changeMock.On("State").Return(pnd.Change_PENDING) + + store := NewChangeStore() + pending := changeMock + if err := store.Add(pending); err != nil { + t.Error(err) + return + } + tests := []struct { + name string + want []uuid.UUID + }{ + { + name: "default", + want: []uuid.UUID{cuid}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + s := store + if got := s.Pending(); !reflect.DeepEqual(got, tt.want) { + t.Errorf("Pending() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestChangeStore_Committed(t *testing.T) { + changeMock := &mocks.Change{} + changeMock.On("ID").Return(cuid) + changeMock.On("State").Return(pnd.Change_COMMITTED) + changeMock.On("Commit").Return(nil) + + store := NewChangeStore() + committed := changeMock + if err := committed.Commit(); err != nil { + t.Error(err) + return + } + if err := store.Add(committed); err != nil { + t.Error(err) + return + } + tests := []struct { + name string + want []uuid.UUID + }{ + { + name: "default", + want: []uuid.UUID{cuid}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + s := store + if got := s.Committed(); !reflect.DeepEqual(got, tt.want) { + t.Errorf("Committed() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestChangeStore_Confirmed(t *testing.T) { + changeMock := &mocks.Change{} + changeMock.On("ID").Return(cuid) + changeMock.On("State").Return(pnd.Change_CONFIRMED) + changeMock.On("Commit").Return(nil) + changeMock.On("Confirm").Return(nil) + + store := NewChangeStore() + confirmed := changeMock + if err := confirmed.Commit(); err != nil { + t.Error(err) + return + } + if err := confirmed.Confirm(); err != nil { + t.Error(err) + return + } + if err := store.Add(confirmed); err != nil { + t.Error(err) + return + } + + tests := []struct { + name string + want []uuid.UUID + }{ + { + name: "default", + want: []uuid.UUID{cuid}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + s := store + if got := s.Confirmed(); !reflect.DeepEqual(got, tt.want) { + t.Errorf("Confirmed() = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_filterChanges(t *testing.T) { + var pendingCUID uuid.UUID + var committedCUID uuid.UUID + var confirmedCUID uuid.UUID + var err error + + pendingCUID, err = uuid.Parse("3e8219b0-e926-400d-8660-217f2a25a7c7") + if err != nil { + log.Fatal(err) + } + committedCUID, err = uuid.Parse("3e8219b0-e926-400d-8660-217f2a25a7c8") + if err != nil { + log.Fatal(err) + } + confirmedCUID, err = uuid.Parse("3e8219b0-e926-400d-8660-217f2a25a7c9") + if err != nil { + log.Fatal(err) + } + + changeMockPending := &mocks.Change{} + changeMockPending.On("ID").Return(pendingCUID) + changeMockPending.On("State").Return(pnd.Change_PENDING) + changeMockPending.On("Commit").Return(nil) + changeMockPending.On("Confirm").Return(nil) + + changeMockCommited := &mocks.Change{} + changeMockCommited.On("ID").Return(committedCUID) + changeMockCommited.On("State").Return(pnd.Change_COMMITTED) + changeMockCommited.On("Commit").Return(nil) + changeMockCommited.On("Confirm").Return(nil) + + changeMockConfirmed := &mocks.Change{} + changeMockConfirmed.On("ID").Return(confirmedCUID) + changeMockConfirmed.On("State").Return(pnd.Change_CONFIRMED) + changeMockConfirmed.On("Commit").Return(nil) + changeMockConfirmed.On("Confirm").Return(nil) + + store := NewChangeStore() + pending := changeMockPending + committed := changeMockCommited + if err := committed.Commit(); err != nil { + t.Error(err) + return + } + confirmed := changeMockConfirmed + if err := confirmed.Commit(); err != nil { + t.Error(err) + return + } + if err := confirmed.Confirm(); err != nil { + t.Error(err) + return + } + if err := store.Add(pending); err != nil { + t.Error(err) + return + } + if err := store.Add(committed); err != nil { + t.Error(err) + return + } + if err := store.Add(confirmed); err != nil { + t.Error(err) + return + } + type args struct { + store *ChangeStore + state ppb.Change_State + } + tests := []struct { + name string + args args + want []uuid.UUID + }{ + { + name: "pending", + args: args{ + store: store, + state: ppb.Change_PENDING, + }, + want: []uuid.UUID{pendingCUID}, + }, + { + name: "committed", + args: args{ + store: store, + state: ppb.Change_COMMITTED, + }, + want: []uuid.UUID{committedCUID}, + }, + { + name: "confirmed", + args: args{ + store: store, + state: ppb.Change_CONFIRMED, + }, + want: []uuid.UUID{confirmedCUID}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := filterChanges(tt.args.store, tt.args.state); !reflect.DeepEqual(got, tt.want) { + t.Errorf("filterChanges() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/store/deviceStore.go b/store/deviceStore.go new file mode 100644 index 0000000000000000000000000000000000000000..df0a9ba85b8fdb266e16dc11148ed03eec8d7e75 --- /dev/null +++ b/store/deviceStore.go @@ -0,0 +1,226 @@ +package store + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "reflect" + + "code.fbi.h-da.de/danet/gosdn/interfaces/device" + "code.fbi.h-da.de/danet/gosdn/interfaces/store" + "code.fbi.h-da.de/danet/gosdn/nucleus/errors" + + "github.com/google/uuid" + log "github.com/sirupsen/logrus" +) + +// DeviceStore is used to store Devices +type DeviceStore struct { + deviceStoreName string + DeviceNameToUUIDLookup map[string]uuid.UUID + *genericStore +} + +// NewDeviceStore returns a DeviceStore +func NewDeviceStore(pndUUID uuid.UUID) *DeviceStore { + return &DeviceStore{ + genericStore: newGenericStore(), + DeviceNameToUUIDLookup: make(map[string]uuid.UUID), + deviceStoreName: fmt.Sprintf("device-store-%s.json", pndUUID.String()), + } +} + +// GetDevice takes a Device's UUID and returns the Device. If the requested +// Device does not exist an error is returned. +func (s *DeviceStore) GetDevice(id uuid.UUID, parseErrors ...error) (device.Device, error) { + var foundID uuid.UUID + + foundID = id + + for _, parseErr := range parseErrors { + if parseErr != nil { + switch e := parseErr.(type) { + case *errors.ErrInvalidUUID: + myID, ok := s.DeviceNameToUUIDLookup[e.DeviceName] + if !ok { + log.Debug(fmt.Sprintf("no device named %s found", foundID)) + return nil, &errors.ErrNotFound{ID: foundID} + } + foundID = myID + } + } + } + + item, err := s.genericStore.Get(foundID) + if err != nil { + return nil, err + } + d, ok := item.(device.Device) + if !ok { + return nil, &errors.ErrInvalidTypeAssertion{ + Value: d, + Type: (*device.Device)(nil), + } + } + log.WithFields(log.Fields{ + "uuid": foundID, + "name": d.Name(), + }).Debug("device was accessed") + + return d, nil +} + +// GetDevicesAssociatedWithSbi ranges over devices within the device store and +// checks if they are associated with the provided SBI. Returns a slice of +// device.Device with all associated devices. +func (s *DeviceStore) GetDevicesAssociatedWithSbi(sid uuid.UUID) ([]device.Device, error) { + var devices []device.Device + // range over all storable items within the device store + for _, item := range s.Store { + d, ok := item.(device.Device) + if !ok { + return nil, &errors.ErrInvalidTypeAssertion{ + Value: d, + Type: reflect.TypeOf((*device.Device)(nil)), + } + } + // check if the device uses the provided SBI and add it to the devices + // slice. + if d.SBI().ID() == sid { + devices = append(devices, d) + } + } + + return devices, nil +} + +// Add adds a device to the device store. +// It also adds the name of the device to the lookup table. +func (s *DeviceStore) Add(item store.Storable, name string) error { + if s.Exists(item.ID()) { + return &errors.ErrAlreadyExists{Item: item} + } + + s.DeviceNameToUUIDLookup[name] = item.ID() + + s.storeLock.Lock() + s.genericStore.Store[item.ID()] = item + s.storeLock.Unlock() + + log.WithFields(log.Fields{ + "type": reflect.TypeOf(item), + "uuid": item.ID(), + }).Debug("storable was added") + + err := s.persist(item, name) + if err != nil { + return err + } + + return nil +} + +// Delete deletes a device from the device store. +func (s *DeviceStore) Delete(id uuid.UUID) error { + if !s.Exists(id) { + return &errors.ErrNotFound{ID: id} + } + + s.storeLock.Lock() + delete(s.genericStore.Store, id) + s.storeLock.Unlock() + + for key, value := range s.DeviceNameToUUIDLookup { + if value == id { + delete(s.DeviceNameToUUIDLookup, key) + } + } + + log.WithFields(log.Fields{ + "uuid": id, + }).Debug("storable was deleted") + + return nil +} + +func (s *DeviceStore) persist(item store.Storable, name string) error { + ensureFilesystemStorePathExists(s.deviceStoreName) + + _, ok := item.(device.Device) + if !ok { + return fmt.Errorf("item is no Device. got=%T", item) + } + + var devicesToPersist []device.Device + + for _, value := range s.genericStore.Store { + dev, ok := value.(device.Device) + if !ok { + return fmt.Errorf("item is no Device. got=%T", item) + } + devicesToPersist = append(devicesToPersist, dev) + } + + storeDataAsJSON, err := json.MarshalIndent(devicesToPersist, "", " ") + if err != nil { + return err + } + + err = ioutil.WriteFile(getCompletePathToFileStore(s.deviceStoreName), storeDataAsJSON, 0644) + if err != nil { + return err + } + + return nil +} + +// LoadedDevice represents a Orchestrated Networking Device that was loaeded +// by using the Load() method of the DeviceStore. +type LoadedDevice struct { + // DeviceID represents the UUID of the LoadedDevice. + DeviceID uuid.UUID `json:"id,omitempty"` + // Name represents the name of the LoadedDevice. + Name string `json:"name,omitempty"` + // TransportType represent the type of the transport in use of the LoadedDevice. + TransportType string `json:"transport_type,omitempty"` + // TransportAddress represents the address from which the device can be reached via the transport method. + TransportAddress string `json:"transport_address,omitempty"` + // TransportUsername is used for authentication via the transport method in use. + TransportUsername string `json:"transport_username,omitempty"` + // TransportPassword is used for authentication via the transport method in use. + TransportPassword string `json:"transport_password,omitempty"` + TransportOptionCsbi bool `json:"transport_option_csbi,omitempty"` + // SBI indicates the southbound interface, which is used by this device as UUID. + SBI uuid.UUID `json:"sbi,omitempty"` +} + +// ID returns the ID of the LoadedDevice as UUID. +func (ld LoadedDevice) ID() uuid.UUID { + return ld.DeviceID +} + +// Load unmarshals the contents of the storage file associated with a DeviceStore +// and returns it as []LoadedDevice. +func (s *DeviceStore) Load() ([]LoadedDevice, error) { + var loadedDevices []LoadedDevice + + err := ensureFilesystemStorePathExists(s.deviceStoreName) + if err != nil { + log.Debug(fmt.Printf("Err: %+v\n", err)) + return loadedDevices, err + } + + dat, err := ioutil.ReadFile(getCompletePathToFileStore(s.deviceStoreName)) + if err != nil { + log.Debug(fmt.Printf("Err: %+v\n", err)) + return loadedDevices, err + } + + err = json.Unmarshal(dat, &loadedDevices) + if err != nil { + log.Debug(fmt.Printf("Err: %+v\n", err)) + return loadedDevices, err + } + + return loadedDevices, nil +} diff --git a/store/device_store_test.go b/store/device_store_test.go new file mode 100644 index 0000000000000000000000000000000000000000..69deb7c67b48376ebf55ceffb534005bdec3b413 --- /dev/null +++ b/store/device_store_test.go @@ -0,0 +1,242 @@ +package store + +import ( + "reflect" + "sync" + "testing" + + "code.fbi.h-da.de/danet/gosdn/interfaces/device" + "code.fbi.h-da.de/danet/gosdn/interfaces/store" + "code.fbi.h-da.de/danet/gosdn/mocks" + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/google/uuid" +) + +func Test_deviceStore_get(t *testing.T) { + deviceMock := &mocks.Device{} + deviceMock.On("ID").Return(did) + deviceMock.On("Name").Return("did") + pndMock := &mocks.NetworkDomain{} + pndMock.On("ID").Return(did) + + type fields struct { + genericStore *genericStore + } + type args struct { + id uuid.UUID + } + tests := []struct { + name string + fields fields + args args + want device.Device + wantErr bool + }{ + { + name: "exists", + fields: fields{ + &genericStore{ + Store: map[uuid.UUID]store.Storable{ + defaultPndID: deviceMock, + }, + storeLock: sync.RWMutex{}, + }, + }, + args: args{id: defaultPndID}, + want: deviceMock, + wantErr: false, + }, + { + name: "fails", + fields: fields{ + &genericStore{ + Store: map[uuid.UUID]store.Storable{ + defaultPndID: deviceMock, + }, + storeLock: sync.RWMutex{}, + }, + }, + args: args{id: iid}, + wantErr: true, + }, + { + name: "fails empty", + fields: fields{ + genericStore: &genericStore{}, + }, + args: args{id: defaultPndID}, + wantErr: true, + }, + { + name: "fails wrong type", + fields: fields{ + &genericStore{ + Store: map[uuid.UUID]store.Storable{ + defaultPndID: pndMock, + }, + storeLock: sync.RWMutex{}, + }, + }, + args: args{id: defaultPndID}, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + s := DeviceStore{genericStore: tt.fields.genericStore} + + got, err := s.GetDevice(FromString(tt.args.id.String())) + if (err != nil) != tt.wantErr { + t.Errorf("get() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("get() got = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_deviceStore_GetDevicesAsssociatedWithSbi(t *testing.T) { + mockSBI := &mocks.SouthboundInterface{} + mockSBI.On("ID").Return(defaultSbiID) + + createDeviceMock := func(name string, sid uuid.UUID) *mocks.Device { + dm := &mocks.Device{} + dm.On("ID").Return(uuid.New()) + dm.On("Name").Return("did") + dm.On("SBI").Return(mockSBI) + return dm + } + + associatedDevices := []device.Device{ + createDeviceMock("mockDevice1", defaultSbiID), + createDeviceMock("mockDevice2", defaultSbiID), + createDeviceMock("mockDevice3", defaultSbiID), + } + + nonAssociatedDevice := createDeviceMock("mockDevice4", uuid.New()) + + pndMock := &mocks.NetworkDomain{} + pndMock.On("ID").Return(did) + + // options to apply to cmp.Equal + opts := []cmp.Option{ + // create custom comparer that simply checks if the device ID's are the + // same. + cmp.Comparer(func(x, y device.Device) bool { + return x.ID() == y.ID() + }), + // compare option to treat slices of length zero as equal + cmpopts.EquateEmpty(), + // sort the slices based on the ID + cmpopts.SortSlices(func(x, y device.Device) bool { + return x.ID().ID() < y.ID().ID() + }), + } + + type fields struct { + genericStore *genericStore + } + type args struct { + sid uuid.UUID + } + tests := []struct { + name string + fields fields + args args + want []device.Device + wantErr bool + }{ + { + name: "return devices associated with SBI", + fields: fields{ + &genericStore{ + Store: map[uuid.UUID]store.Storable{ + associatedDevices[0].ID(): associatedDevices[0], + associatedDevices[1].ID(): associatedDevices[1], + associatedDevices[2].ID(): associatedDevices[2], + }, + storeLock: sync.RWMutex{}, + }, + }, + args: args{ + sid: defaultSbiID, + }, + want: associatedDevices, + wantErr: false, + }, + { + name: "non associated devices should not be part of the returned slice", + fields: fields{ + &genericStore{ + Store: map[uuid.UUID]store.Storable{ + associatedDevices[0].ID(): associatedDevices[0], + associatedDevices[1].ID(): associatedDevices[1], + associatedDevices[2].ID(): associatedDevices[2], + nonAssociatedDevice.ID(): nonAssociatedDevice, + }, + storeLock: sync.RWMutex{}, + }, + }, + args: args{ + sid: defaultSbiID, + }, + want: append(associatedDevices, nonAssociatedDevice), + wantErr: false, + }, + { + name: "empty", + fields: fields{ + &genericStore{ + Store: map[uuid.UUID]store.Storable{}, + storeLock: sync.RWMutex{}, + }, + }, + want: []device.Device{}, + wantErr: false, + }, + { + name: "no device associated", + fields: fields{ + &genericStore{ + Store: map[uuid.UUID]store.Storable{ + nonAssociatedDevice.ID(): nonAssociatedDevice, + }, + storeLock: sync.RWMutex{}, + }, + }, + want: []device.Device{}, + wantErr: false, + }, + { + name: "fails wrong type", + fields: fields{ + &genericStore{ + Store: map[uuid.UUID]store.Storable{ + defaultPndID: pndMock, + }, + storeLock: sync.RWMutex{}, + }, + }, + args: args{sid: defaultSbiID}, + want: nil, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + s := DeviceStore{genericStore: tt.fields.genericStore} + + got, err := s.GetDevicesAssociatedWithSbi(tt.args.sid) + if (err != nil) != tt.wantErr { + t.Errorf("GetDevicesAssociatedWithSbi() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !cmp.Equal(got, tt.want, opts...) { + t.Errorf("GetDevicesAssociatedWithSbi() got = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/store/genericStore.go b/store/genericStore.go new file mode 100644 index 0000000000000000000000000000000000000000..83d6bb9333403bc868611c17c29d70c271bfd337 --- /dev/null +++ b/store/genericStore.go @@ -0,0 +1,89 @@ +package store + +import ( + "reflect" + "sync" + + "code.fbi.h-da.de/danet/gosdn/interfaces/store" + "code.fbi.h-da.de/danet/gosdn/nucleus/errors" + + "github.com/google/uuid" + log "github.com/sirupsen/logrus" +) + +// newGenericStore returns a genericStore +func newGenericStore() *genericStore { + return &genericStore{Store: make(map[uuid.UUID]store.Storable), storeLock: sync.RWMutex{}} +} + +type genericStore struct { + Store map[uuid.UUID]store.Storable + storeLock sync.RWMutex +} + +// Exists takes a Storable's UUID and checks its existence in the store. +func (s *genericStore) Exists(id uuid.UUID) bool { + s.storeLock.RLock() + defer s.storeLock.RUnlock() + _, ok := s.Store[id] + return ok +} + +// Add adds a Storable to the Store +func (s *genericStore) Add(item store.Storable) error { + if s.Exists(item.ID()) { + return &errors.ErrAlreadyExists{Item: item} + } + s.storeLock.Lock() + s.Store[item.ID()] = item + s.storeLock.Unlock() + log.WithFields(log.Fields{ + "type": reflect.TypeOf(item), + "uuid": item.ID(), + }).Debug("storable was added") + return nil +} + +// Get takes a Storable's UUID and returns the Storable. If the requested +// Storable does not exist an error is returned. Get is only type safe for +// this Storable interface. For type safe get operations on specialised stores +// use GetDevice, GetPND, GetSBI, or GetChange respectively. +func (s *genericStore) Get(id uuid.UUID) (store.Storable, error) { + if !s.Exists(id) { + return nil, &errors.ErrNotFound{ID: id} + } + log.WithFields(log.Fields{ + "uuid": id, + }).Debug("storable was accessed") + s.storeLock.RLock() + defer s.storeLock.RUnlock() + return s.Store[id], nil +} + +// Delete takes a Storable's UUID and deletes it. If the specified UUID does not +// exist in the Store an error is returned. +func (s *genericStore) Delete(id uuid.UUID) error { + if !s.Exists(id) { + return &errors.ErrNotFound{ID: id} + } + s.storeLock.Lock() + delete(s.Store, id) + s.storeLock.Unlock() + log.WithFields(log.Fields{ + "uuid": id, + }).Debug("storable was deleted") + return nil +} + +// UUIDs returns all UUIDs in the store. +func (s *genericStore) UUIDs() []uuid.UUID { + s.storeLock.RLock() + defer s.storeLock.RUnlock() + keys := make([]uuid.UUID, len(s.Store)) + i := 0 + for k := range s.Store { + keys[i] = k + i++ + } + return keys +} diff --git a/store/generic_store_test.go b/store/generic_store_test.go new file mode 100644 index 0000000000000000000000000000000000000000..feb55d5b1dd68fbc48fc4e54648601253ff42e66 --- /dev/null +++ b/store/generic_store_test.go @@ -0,0 +1,242 @@ +package store + +import ( + "reflect" + "sort" + "testing" + + "code.fbi.h-da.de/danet/gosdn/interfaces/store" + "code.fbi.h-da.de/danet/gosdn/mocks" + "github.com/google/uuid" +) + +func Test_Store_add(t *testing.T) { + type args struct { + item store.Storable + } + tests := []struct { + name string + s *genericStore + args args + wantErr bool + }{ + { + name: "default", + s: newGenericStore(), + args: args{ + item: &mocks.Storable{}, + }, + }, + { + name: "already exists", + s: &genericStore{ + Store: map[uuid.UUID]store.Storable{ + iid: &mocks.Storable{}, + }, + }, + args: args{ + item: &mocks.Storable{}, + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tt.args.item.(*mocks.Storable).On("ID").Return(iid) + switch tt.name { + case "already exixts": + _ = tt.s.Add(tt.args.item) + default: + } + if err := tt.s.Add(tt.args.item); (err != nil) != tt.wantErr { + t.Errorf("Add() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func Test_Store_delete(t *testing.T) { + type args struct { + id uuid.UUID + } + tests := []struct { + name string + s *genericStore + args args + wantErr bool + }{ + { + name: "default", + s: &genericStore{ + Store: map[uuid.UUID]store.Storable{ + iid: &mocks.Storable{}, + }, + }, + args: args{id: iid}, + wantErr: false, + }, + { + name: "not found empty", + s: newGenericStore(), + args: args{id: iid}, + wantErr: true, + }, + { + name: "not found", + s: &genericStore{ + Store: map[uuid.UUID]store.Storable{ + iid: &mocks.Storable{}, + }, + }, + args: args{id: altIid}, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := tt.s.Delete(tt.args.id); (err != nil) != tt.wantErr { + t.Errorf("delete() error = %v, wantErr %v", err, tt.wantErr) + } + if tt.name == "default" { + item, ok := tt.s.Store[iid] + if ok { + t.Errorf("delete() item %v still in genericStore %v", item, tt.s) + } + } + }) + } +} + +func Test_Store_exists(t *testing.T) { + type args struct { + id uuid.UUID + } + tests := []struct { + name string + s *genericStore + args args + want bool + }{ + { + name: "default", + s: &genericStore{ + Store: map[uuid.UUID]store.Storable{ + iid: &mocks.Storable{}, + }, + }, + args: args{id: iid}, + want: true, + }, + { + name: "not found empty", + s: newGenericStore(), + args: args{id: iid}, + want: false, + }, + { + name: "not found", + s: &genericStore{ + Store: map[uuid.UUID]store.Storable{ + iid: &mocks.Storable{}, + }, + }, + args: args{id: altIid}, + want: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := tt.s.Exists(tt.args.id); got != tt.want { + t.Errorf("exists() = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_Store_get(t *testing.T) { + type args struct { + id uuid.UUID + } + tests := []struct { + name string + s *genericStore + args args + want store.Storable + wantErr bool + }{ + { + name: "exists", + s: &genericStore{ + Store: map[uuid.UUID]store.Storable{ + iid: &mocks.Storable{}, + }, + }, + args: args{id: iid}, + want: &mocks.Storable{}, + wantErr: false, + }, + { + name: "not found", + s: &genericStore{ + Store: map[uuid.UUID]store.Storable{ + iid: &mocks.Storable{}, + }, + }, + args: args{id: altIid}, + want: nil, + wantErr: true, + }, + { + name: "not found empty", + s: newGenericStore(), + args: args{id: iid}, + want: nil, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := tt.s.Get(tt.args.id) + if (err != nil) != tt.wantErr { + t.Errorf("get() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("get() got = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_Store_UUIDs(t *testing.T) { + tests := []struct { + name string + s *genericStore + want []uuid.UUID + }{ + { + name: "default", + s: &genericStore{ + Store: map[uuid.UUID]store.Storable{ + iid: &mocks.Storable{}, + altIid: &mocks.Storable{}, + }, + }, + want: []uuid.UUID{iid, altIid}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + sort.Slice(tt.want, func(i, j int) bool { + return tt.want[i].String() < tt.want[j].String() + }) + got := tt.s.UUIDs() + sort.Slice(got, func(i, j int) bool { + return got[i].String() < got[j].String() + }) + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("UUIDs() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/store/initialise_test.go b/store/initialise_test.go new file mode 100644 index 0000000000000000000000000000000000000000..732bad161a89a0fe8a7d9b7e92bf261a027e6031 --- /dev/null +++ b/store/initialise_test.go @@ -0,0 +1,60 @@ +package store + +import ( + "os" + "testing" + + "github.com/google/uuid" + log "github.com/sirupsen/logrus" +) + +// UUIDs for test cases +var mdid uuid.UUID +var defaultPndID uuid.UUID +var cuid uuid.UUID +var did uuid.UUID +var iid uuid.UUID +var altIid uuid.UUID +var defaultSbiID uuid.UUID + +func TestMain(m *testing.M) { + log.SetReportCaller(true) + + if os.Getenv("GOSDN_LOG") == "nolog" { + log.SetLevel(log.PanicLevel) + } + readTestUUIDs() + os.Exit(m.Run()) +} + +func readTestUUIDs() { + var err error + mdid, err = uuid.Parse("688a264e-5f85-40f8-bd13-afc42fcd5c7a") + if err != nil { + log.Fatal(err) + } + defaultPndID, err = uuid.Parse("b4016412-eec5-45a1-aa29-f59915357bad") + if err != nil { + log.Fatal(err) + } + cuid, err = uuid.Parse("3e8219b0-e926-400d-8660-217f2a25a7c6") + if err != nil { + log.Fatal(err) + } + did, err = uuid.Parse("4d8246f8-e884-41d6-87f5-c2c784df9e44") + if err != nil { + log.Fatal(err) + } + iid, err = uuid.Parse("8495a8ac-a1e8-418e-b787-10f5878b2690") + if err != nil { + log.Fatal(err) + } + altIid, err = uuid.Parse("edc5de93-2d15-4586-b2a7-fb1bc770986b") + if err != nil { + log.Fatal(err) + } + defaultSbiID, err = uuid.Parse("b70c8425-68c7-4d4b-bb5e-5586572bd64b") + if err != nil { + log.Fatal(err) + } +} diff --git a/store/pndStore.go b/store/pndStore.go new file mode 100644 index 0000000000000000000000000000000000000000..deff904fdf1cea5cba708484164486139fd65977 --- /dev/null +++ b/store/pndStore.go @@ -0,0 +1,170 @@ +package store + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "reflect" + + tpb "code.fbi.h-da.de/danet/api/go/gosdn/transport" + "code.fbi.h-da.de/danet/gosdn/interfaces/networkdomain" + "code.fbi.h-da.de/danet/gosdn/interfaces/store" + "code.fbi.h-da.de/danet/gosdn/nucleus/errors" + "github.com/google/uuid" + log "github.com/sirupsen/logrus" +) + +// DeviceDetails contains details of a device used by the cSBI mechanism +type DeviceDetails struct { + ID string + Address string + TransportOption *tpb.TransportOption +} + +// PndStore is used to store PrincipalNetworkDomains +type PndStore struct { + pndStoreName string + pendingChannels map[uuid.UUID]chan DeviceDetails + *genericStore +} + +// NewPndStore returns a PndStore +func NewPndStore() *PndStore { + return &PndStore{ + genericStore: newGenericStore(), + pendingChannels: make(map[uuid.UUID]chan DeviceDetails), + pndStoreName: "pnd-store.json"} +} + +// GetPND takes a PrincipalNetworkDomain's UUID and returns the PrincipalNetworkDomain. If the requested +// PrincipalNetworkDomain does not exist an error is returned. +func (s *PndStore) GetPND(id uuid.UUID) (networkdomain.NetworkDomain, error) { + item, err := s.genericStore.Get(id) + if err != nil { + return nil, err + } + pnd, ok := item.(networkdomain.NetworkDomain) + if !ok { + return nil, &errors.ErrInvalidTypeAssertion{ + Value: pnd, + Type: (*networkdomain.NetworkDomain)(nil), + } + } + log.WithFields(log.Fields{ + "uuid": id, + }).Debug("principal network domain was accessed") + return pnd, nil +} + +// Add adds a device to the device store. +// It also adds the name of the device to the lookup table. +func (s *PndStore) Add(item store.Storable) error { + if s.Exists(item.ID()) { + return &errors.ErrAlreadyExists{Item: item} + } + + s.storeLock.Lock() + s.genericStore.Store[item.ID()] = item + s.storeLock.Unlock() + + log.WithFields(log.Fields{ + "type": reflect.TypeOf(item), + "uuid": item.ID(), + }).Debug("storable was added") + + err := s.persist(item) + if err != nil { + return err + } + + return nil +} + +// PendingChannels holds channels used communicate with pending +// cSBI deployments +func (s *PndStore) PendingChannels(id uuid.UUID, parseErrors ...error) (chan DeviceDetails, error) { + ch, ok := s.pendingChannels[id] + if !ok { + return nil, &errors.ErrNotFound{ID: id} + } + return ch, nil +} + +// AddPendingChannel adds a pending channel to the map +func (s *PndStore) AddPendingChannel(id uuid.UUID, ch chan DeviceDetails) { + s.pendingChannels[id] = ch +} + +// RemovePendingChannel removes a pending channel from the map +func (s *PndStore) RemovePendingChannel(id uuid.UUID) { + delete(s.pendingChannels, id) +} + +func (s *PndStore) persist(item store.Storable) error { + ensureFilesystemStorePathExists(s.pndStoreName) + + _, ok := item.(networkdomain.NetworkDomain) + if !ok { + return fmt.Errorf("item is no NetworkDoman. got=%T", item) + } + + var networkDomainsToPersist []LoadedPnd + + for _, value := range s.genericStore.Store { + networkDomain, ok := value.(networkdomain.NetworkDomain) + if !ok { + return fmt.Errorf("item is no Device. got=%T", item) + } + networkDomainsToPersist = append(networkDomainsToPersist, LoadedPnd{ + Name: networkDomain.GetName(), + Description: networkDomain.GetDescription(), + ID: networkDomain.ID(), + }) + } + + storeDataAsJSON, err := json.MarshalIndent(networkDomainsToPersist, "", " ") + if err != nil { + return err + } + + err = ioutil.WriteFile(getCompletePathToFileStore(s.pndStoreName), storeDataAsJSON, 0644) + if err != nil { + return err + } + + return nil +} + +// LoadedPnd represents a Principal Network Domain that was loaeded by using +// the Load() method of the PndStore. +type LoadedPnd struct { + ID uuid.UUID `json:"id,omitempty"` + Name string `json:"name,omitempty"` + Description string `json:"description,omitempty"` +} + +// Load unmarshals the contents of the storage file associated with a PndStore +// and returns it as []LoadedPnd. +func (s *PndStore) Load() ([]LoadedPnd, error) { + var loadedNetworkDomains []LoadedPnd + + err := ensureFilesystemStorePathExists(s.pndStoreName) + if err != nil { + log.Debug(fmt.Printf("Err: %+v\n", err)) + return loadedNetworkDomains, err + } + + dat, err := ioutil.ReadFile(getCompletePathToFileStore(s.pndStoreName)) + if err != nil { + log.Debug(fmt.Printf("Err: %+v\n", err)) + return loadedNetworkDomains, err + } + + err = json.Unmarshal(dat, &loadedNetworkDomains) + if err != nil { + log.Debug(fmt.Printf("Err: %+v\n", err)) + return loadedNetworkDomains, err + } + + return loadedNetworkDomains, nil +} diff --git a/store/pnd_store_test.go b/store/pnd_store_test.go new file mode 100644 index 0000000000000000000000000000000000000000..5cd8bbbbfa42bb2aa4c44c2812bf1bf22abd73d7 --- /dev/null +++ b/store/pnd_store_test.go @@ -0,0 +1,82 @@ +package store + +import ( + "reflect" + "sync" + "testing" + + "code.fbi.h-da.de/danet/gosdn/interfaces/networkdomain" + "code.fbi.h-da.de/danet/gosdn/interfaces/store" + "code.fbi.h-da.de/danet/gosdn/mocks" + "github.com/google/uuid" +) + +func Test_pndStore_get(t *testing.T) { + pndMock := &mocks.NetworkDomain{} + pndMock.On("ID").Return(defaultPndID) + + type fields struct { + genericStore *genericStore + } + type args struct { + id uuid.UUID + } + tests := []struct { + name string + fields fields + args args + want networkdomain.NetworkDomain + wantErr bool + }{ + { + name: "exists", + fields: fields{ + &genericStore{ + Store: map[uuid.UUID]store.Storable{ + defaultPndID: pndMock, + }, + storeLock: sync.RWMutex{}, + }, + }, + args: args{id: defaultPndID}, + want: pndMock, + wantErr: false, + }, + { + name: "fails", + fields: fields{ + &genericStore{ + Store: map[uuid.UUID]store.Storable{ + defaultPndID: pndMock, + }, + storeLock: sync.RWMutex{}, + }, + }, + args: args{id: iid}, + wantErr: true, + }, + { + name: "fails empty", + fields: fields{ + genericStore: &genericStore{}, + }, + args: args{id: defaultPndID}, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + s := PndStore{ + genericStore: tt.fields.genericStore, + } + got, err := s.Get(tt.args.id) + if (err != nil) != tt.wantErr { + t.Errorf("get() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("get() got = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/store/sbiStore.go b/store/sbiStore.go new file mode 100644 index 0000000000000000000000000000000000000000..f74d31092cef87ace0682015110a1a0195f8845b --- /dev/null +++ b/store/sbiStore.go @@ -0,0 +1,39 @@ +package store + +import ( + "code.fbi.h-da.de/danet/gosdn/interfaces/southbound" + "code.fbi.h-da.de/danet/gosdn/nucleus/errors" + + "github.com/google/uuid" + log "github.com/sirupsen/logrus" +) + +// SbiStore is used to store SouthboundInterfaces +type SbiStore struct { + *genericStore +} + +// NewSbiStore returns a SbiStore +func NewSbiStore() *SbiStore { + return &SbiStore{genericStore: newGenericStore()} +} + +// GetSBI takes a SouthboundInterface's UUID and returns the SouthboundInterface. If the requested +// SouthboundInterface does not exist an error is returned. +func (s *SbiStore) GetSBI(id uuid.UUID) (southbound.SouthboundInterface, error) { + item, err := s.Get(id) + if err != nil { + return nil, err + } + sbi, ok := item.(southbound.SouthboundInterface) + if !ok { + return nil, &errors.ErrInvalidTypeAssertion{ + Value: sbi, + Type: (*southbound.SouthboundInterface)(nil), + } + } + log.WithFields(log.Fields{ + "uuid": id, + }).Debug("southbound interface was accessed") + return sbi, nil +} diff --git a/store/sbi_store_test.go b/store/sbi_store_test.go new file mode 100644 index 0000000000000000000000000000000000000000..2dc294639a6947f6c31374a97b75034297647027 --- /dev/null +++ b/store/sbi_store_test.go @@ -0,0 +1,82 @@ +package store + +import ( + "reflect" + "sync" + "testing" + + "code.fbi.h-da.de/danet/gosdn/interfaces/southbound" + "code.fbi.h-da.de/danet/gosdn/interfaces/store" + "code.fbi.h-da.de/danet/gosdn/mocks" + + "github.com/google/uuid" +) + +func Test_sbiStore_get(t *testing.T) { + openConfig := &mocks.SouthboundInterface{} + openConfig.On("ID").Return(defaultSbiID) + + type fields struct { + genericStore *genericStore + } + type args struct { + id uuid.UUID + } + tests := []struct { + name string + fields fields + args args + want southbound.SouthboundInterface + wantErr bool + }{ + { + name: "exists", + fields: fields{ + &genericStore{ + Store: map[uuid.UUID]store.Storable{ + defaultSbiID: openConfig, + }, + storeLock: sync.RWMutex{}, + }, + }, + args: args{id: defaultSbiID}, + want: openConfig, + wantErr: false, + }, + { + name: "fails", + fields: fields{ + &genericStore{ + Store: map[uuid.UUID]store.Storable{ + defaultSbiID: openConfig, + }, + storeLock: sync.RWMutex{}, + }, + }, + args: args{id: iid}, + wantErr: true, + }, + { + name: "fails empty", + fields: fields{ + genericStore: &genericStore{}, + }, + args: args{id: defaultSbiID}, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + s := SbiStore{genericStore: tt.fields.genericStore} + + got, err := s.Get(tt.args.id) + if (err != nil) != tt.wantErr { + t.Errorf("get() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("get() got = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/store/utils.go b/store/utils.go new file mode 100644 index 0000000000000000000000000000000000000000..074edab53ca811f440092b1c05530f4b3c43111a --- /dev/null +++ b/store/utils.go @@ -0,0 +1,74 @@ +package store + +import ( + "fmt" + "os" + "path/filepath" + + "code.fbi.h-da.de/danet/gosdn/nucleus/errors" + "github.com/google/uuid" + log "github.com/sirupsen/logrus" +) + +const ( + pathToStores string = "stores" +) + +// FromString is a helper to check if a provided string as a valid UUID or a name. +func FromString(id string) (uuid.UUID, error) { + idAsUUID, err := uuid.Parse(id) + + // id is no UUID therefore it could be a device name. + // The name will be returned within the error. + if err != nil { + log.WithFields(log.Fields{ + "identifier": id, + }).Debug(err) + return uuid.Nil, &errors.ErrInvalidUUID{DeviceName: id} + } + + return idAsUUID, nil +} + +func ensureFilesystemStorePathExists(storeFileName string) error { + completeStorePath := filepath.Join(pathToStores, storeFileName) + if _, err := os.Stat(completeStorePath); os.IsNotExist(err) { + err := ensureFileSystemStoreExists(completeStorePath) + if err != nil { + return err + } + } + + return nil +} + +func ensureFileSystemStoreExists(pathToStore string) error { + err := ensureDirExists(pathToStore) + if err != nil { + return err + } + + emptyArray := []byte("[]") + err = os.WriteFile(pathToStore, emptyArray, 0600) + if err != nil { + return err + } + + return nil +} + +func ensureDirExists(fileName string) error { + dirName := filepath.Dir(fileName) + if _, serr := os.Stat(dirName); serr != nil { + merr := os.MkdirAll(dirName, os.ModePerm) + if merr != nil { + return merr + } + } + + return nil +} + +func getCompletePathToFileStore(storeName string) string { + return fmt.Sprintf("%s/%s", pathToStores, storeName) +} diff --git a/test/containerlab/complex-1.0.clab.tmpl.yml b/test/containerlab/complex-1.0.clab.tmpl.yml new file mode 100644 index 0000000000000000000000000000000000000000..cdec98b888e1aff0bd56b69cd863f10aa928ef21 --- /dev/null +++ b/test/containerlab/complex-1.0.clab.tmpl.yml @@ -0,0 +1,79 @@ +# topology documentation: http://containerlab.srlinux.dev/lab-examples/srl-ceos/ +name: @@CLAB_NAME@@ + +mgmt: + network: @@CLAB_NAME@@ + ipv4_subnet: @@CLAB_MGMT_SUBNET@@ + +topology: + nodes: + gosdn: + kind: linux + image: @@GOSDN_CONTAINER_IMAGE@@ + ports: + - 0:8080 + - 0:55055 + ceos1-1: + kind: ceos + image: @@CEOS_CONTAINER_IMAGE@@ + ports: + - 0:6030 + ceos1-2: + kind: ceos + image: @@CEOS_CONTAINER_IMAGE@@ + ports: + - 0:6030 + ceos2-1-1: + kind: ceos + image: @@CEOS_CONTAINER_IMAGE@@ + ports: + - 0:6030 + ceos2-1-2: + kind: ceos + image: @@CEOS_CONTAINER_IMAGE@@ + ports: + - 0:6030 + ceos2-2-1: + kind: ceos + image: @@CEOS_CONTAINER_IMAGE@@ + ports: + - 0:6030 + ceos2-2-2: + kind: ceos + image: @@CEOS_CONTAINER_IMAGE@@ + ports: + - 0:6030 + server3-1-1: + kind: linux + image: alpine:latest + server3-1-2: + kind: linux + image: alpine:latest + server3-1-3: + kind: linux + image: alpine:latest + server3-2-1: + kind: linux + image: alpine:latest + server3-2-2: + kind: linux + image: alpine:latest + + + links: + - endpoints: ["ceos1-1:eth1", "ceos2-1-1:eth1"] + - endpoints: ["ceos1-1:eth2", "ceos2-1-2:eth1"] + - endpoints: ["ceos1-1:eth3", "ceos2-2-1:eth1"] + - endpoints: ["ceos1-1:eth4", "ceos2-2-2:eth1"] + - endpoints: ["ceos1-2:eth1", "ceos2-1-1:eth2"] + - endpoints: ["ceos1-2:eth2", "ceos2-1-2:eth2"] + - endpoints: ["ceos1-2:eth3", "ceos2-2-1:eth2"] + - endpoints: ["ceos1-2:eth4", "ceos2-2-2:eth2"] + - endpoints: ["ceos2-1-1:eth3", "server3-1-1:eth1"] + - endpoints: ["ceos2-1-1:eth4", "server3-1-2:eth1"] + - endpoints: ["ceos2-1-2:eth3", "server3-1-2:eth2"] + - endpoints: ["ceos2-1-2:eth4", "server3-1-3:eth1"] + - endpoints: ["ceos2-2-1:eth3", "server3-2-1:eth1"] + - endpoints: ["ceos2-2-1:eth4", "server3-2-2:eth1"] + - endpoints: ["ceos2-2-2:eth3d", "server3-2-1:eth2"] + - endpoints: ["ceos2-2-2:eth4", "server3-2-2:eth2"] diff --git a/test/containerlab/complex-1.0.png b/test/containerlab/complex-1.0.png new file mode 100644 index 0000000000000000000000000000000000000000..7e68e19f8fee69e1e78d632339971f4c3f853e7a Binary files /dev/null and b/test/containerlab/complex-1.0.png differ diff --git a/test/containerlab/dev.clab.tmpl.yml b/test/containerlab/dev.clab.tmpl.yml new file mode 100644 index 0000000000000000000000000000000000000000..985bd75394a310f93eac3dc276bcd10274126700 --- /dev/null +++ b/test/containerlab/dev.clab.tmpl.yml @@ -0,0 +1,30 @@ +# topology documentation: http://containerlab.srlinux.dev/lab-examples/srl-ceos/ +name: @@CLAB_NAME@@ + +mgmt: + network: clab-@@CLAB_NAME@@ + ipv4_subnet: @@CLAB_MGMT_SUBNET@@ + +topology: + kinds: + ceos: + image: @@CEOS_CONTAINER_IMAGE@@ + nodes: + ceos1: + kind: ceos + ceos2: + kind: ceos + ceos3: + kind: ceos + + gosdn: + kind: linux + image: @@GOSDN_CONTAINER_IMAGE@@ + ports: + - 8080:8080 + - 55055:55055 + + links: + - endpoints: ["ceos1:eth1", "ceos2:eth1"] + - endpoints: ["ceos1:eth2", "ceos3:eth1"] + - endpoints: ["ceos2:eth2", "ceos3:eth2"] diff --git a/test/containerlab/int01.clab.tmpl.yml b/test/containerlab/int01.clab.tmpl.yml new file mode 100644 index 0000000000000000000000000000000000000000..10512cce11f3c85331c695cfe5c7aed1dfff67f3 --- /dev/null +++ b/test/containerlab/int01.clab.tmpl.yml @@ -0,0 +1,23 @@ +# topology documentation: http://containerlab.srlinux.dev/lab-examples/srl-ceos/ +name: @@CLAB_NAME@@ + +mgmt: + network: @@CLAB_NAME@@ + ipv4_subnet: @@CLAB_MGMT_SUBNET@@ + +topology: + kinds: + ceos: + image: @@CEOS_CONTAINER_IMAGE@@ + nodes: + ceos1: + kind: ceos + ports: + - 0:6030 + + gosdn: + kind: linux + image: @@GOSDN_CONTAINER_IMAGE@@ + ports: + - 0:8080 + - 0:55055 diff --git a/test/integration/cliIntegration_test.go b/test/integration/cliIntegration_test.go deleted file mode 100644 index d2800b0e0c434d2cf8c9bf2fd6972a03ab1d0a71..0000000000000000000000000000000000000000 --- a/test/integration/cliIntegration_test.go +++ /dev/null @@ -1,194 +0,0 @@ -package integration - -import ( - "code.fbi.h-da.de/cocsn/gosdn/cli" - "testing" -) - -func TestCapabilities(t *testing.T) { - if testing.Short() { - t.Skip("skipping integration test") - } - type args struct { - a string - u string - p string - } - tests := []struct { - name string - args args - wantErr bool - }{ - { - name: "default", - args: args{ - a: testAddress, - u: testUsername, - p: testPassword, - }, - wantErr: false, - }, - { - name: "destination unreachable", - args: args{ - a: unreachable, - u: testUsername, - p: testPassword, - }, - wantErr: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if err := cli.Capabilities(tt.args.a, tt.args.u, tt.args.p); (err != nil) != tt.wantErr { - t.Errorf("Capabilities() error = %v, wantErr %v", err, tt.wantErr) - } - }) - } -} - -func TestGet(t *testing.T) { - if testing.Short() { - t.Skip("skipping integration test") - } - type args struct { - a string - u string - p string - args []string - } - tests := []struct { - name string - args args - wantErr bool - }{ - { - name: "default", - args: args{ - a: testAddress, - u: testUsername, - p: testPassword, - args: defaultPath, - }, - wantErr: false, - }, - { - name: "destination unreachable", - args: args{ - a: unreachable, - u: testUsername, - p: testPassword, - args: defaultPath, - }, - wantErr: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if _, err := cli.Get(tt.args.a, tt.args.u, tt.args.p, tt.args.args...); (err != nil) != tt.wantErr { - t.Errorf("Get() error = %v, wantErr %v", err, tt.wantErr) - } - }) - } -} - -func TestHttpGet(t *testing.T) { - if testing.Short() { - t.Skip("skipping integration test") - } - type args struct { - apiEndpoint string - f string - args []string - } - tests := []struct { - name string - args args - wantErr bool - }{ - { - name: "default", - args: args{ - apiEndpoint: testAPIEndpoint, - f: "init", - args: nil, - }, - wantErr: false, - }, - { - name: "destination unreachable", - args: args{ - apiEndpoint: "http://" + unreachable, - f: "init", - args: nil, - }, - wantErr: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if err := cli.HTTPGet(tt.args.apiEndpoint, tt.args.f, tt.args.args...); (err != nil) != tt.wantErr { - t.Errorf("HttpGet() error = %v, wantErr %v", err, tt.wantErr) - } - }) - } -} - -func TestSet(t *testing.T) { - if testing.Short() { - t.Skip("skipping integration test") - } - type args struct { - a string - u string - p string - typ string - args []string - } - tests := []struct { - name string - args args - wantErr bool - }{ - { - name: "default", - args: args{ - a: testAddress, - u: testUsername, - p: testPassword, - typ: "update", - args: []string{"/system/config/hostname", "ceos3000"}, - }, - wantErr: false, - }, - { - name: "destination unreachable", - args: args{ - a: unreachable, - u: testUsername, - p: testPassword, - typ: "update", - args: []string{"/system/config/hostname", "ceos3000"}, - }, - wantErr: true, - }, - { - name: "invalid path", - args: args{ - a: testAddress, - u: testUsername, - p: testPassword, - typ: "update", - args: []string{"invalid/path", "ceos3000"}, - }, - wantErr: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if err := cli.Set(tt.args.a, tt.args.u, tt.args.p, tt.args.typ, tt.args.args...); (err != nil) != tt.wantErr { - t.Errorf("Set() error = %v, wantErr %v", err, tt.wantErr) - } - }) - } -} diff --git a/test/integration/cmdIntegration_test.go b/test/integration/cmdIntegration_test.go deleted file mode 100644 index 0aefff4db74566a9dc411cc76de8c4965766570a..0000000000000000000000000000000000000000 --- a/test/integration/cmdIntegration_test.go +++ /dev/null @@ -1,180 +0,0 @@ -package integration - -import ( - "code.fbi.h-da.de/cocsn/gosdn/cli" - "code.fbi.h-da.de/cocsn/gosdn/forks/goarista/gnmi" - "code.fbi.h-da.de/cocsn/gosdn/nucleus" - "code.fbi.h-da.de/cocsn/gosdn/nucleus/util/proto" - guuid "github.com/google/uuid" - gpb "github.com/openconfig/gnmi/proto/gnmi" - log "github.com/sirupsen/logrus" - "github.com/spf13/viper" - pb "google.golang.org/protobuf/proto" - "os" - "testing" -) - -const unreachable = "203.0.113.10:6030" - -var testAddress = "141.100.67.238:6030" -var testAPIEndpoint = "http://gosdn-latest.apps.ocp.fbi.h-da.de/api" -var testUsername = "admin" -var testPassword = "arista" -var defaultPath = []string{"/system/config/hostname"} -var opt *nucleus.GnmiTransportOptions - -func TestMain(m *testing.M) { - testSetupIntegration() - os.Exit(m.Run()) -} - - -func testSetupIntegration() { - if os.Getenv("GOSDN_LOG") == "nolog" { - log.SetLevel(log.PanicLevel) - } - - a := os.Getenv("GOSDN_TEST_ENDPOINT") - if a != "" { - testAddress = a - log.Infof("GOSDN_TEST_ENDPOINT set to %v", testAddress) - } - api := os.Getenv("GOSDN_TEST_API_ENDPOINT") - if api != "" { - testAPIEndpoint = api - log.Infof("GOSDN_TEST_API_ENDPOINT set to %v", testAPIEndpoint) - } - u := os.Getenv("GOSDN_TEST_USER") - if u != "" { - testUsername = u - log.Infof("GOSDN_TEST_USER set to %v", testUsername) - } - p := os.Getenv("GOSDN_TEST_PASSWORD") - if p != "" { - testPassword = p - log.Infof("GOSDN_TEST_PASSWORD set to %v", testPassword) - } - - gnmiMessages = map[string]pb.Message{ - "../proto/cap-resp-arista-ceos": &gpb.CapabilityResponse{}, - "../proto/req-full-node": &gpb.GetRequest{}, - "../proto/req-full-node-arista-ceos": &gpb.GetRequest{}, - "../proto/req-interfaces-arista-ceos": &gpb.GetRequest{}, - "../proto/req-interfaces-interface-arista-ceos": &gpb.GetRequest{}, - "../proto/req-interfaces-wildcard": &gpb.GetRequest{}, - "../proto/resp-full-node": &gpb.GetResponse{}, - "../proto/resp-full-node-arista-ceos": &gpb.GetResponse{}, - "../proto/resp-interfaces-arista-ceos": &gpb.GetResponse{}, - "../proto/resp-interfaces-interface-arista-ceos": &gpb.GetResponse{}, - "../proto/resp-interfaces-wildcard": &gpb.GetResponse{}, - "../proto/resp-set-system-config-hostname": &gpb.SetResponse{}, - } - for k, v := range gnmiMessages { - if err := proto.Read(k, v); err != nil { - log.Fatalf("error parsing %v: %v", k, err) - } - } - - opt = &nucleus.GnmiTransportOptions{ - Config: gnmi.Config{ - Addr: testAddress, - Username: testUsername, - Password: testPassword, - Encoding: gpb.Encoding_JSON_IETF, - }, - RespChan: make(chan *gpb.SubscribeResponse), - } -} - -func TestCliIntegration(t *testing.T) { - if testing.Short() { - t.Skip("skipping integration test") - } - tests := []struct { - name string - wantErr bool - }{ - { - name: "default", - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - defer viper.Reset() - if err := cli.HTTPGet(testAPIEndpoint, "init"); (err != nil) != tt.wantErr { - switch err.(type) { - case viper.ConfigFileNotFoundError: - default: - t.Errorf("gosdn cli init error = %v, wantErr %v", err, tt.wantErr) - return - } - } - cliPnd := viper.GetString("CLI_PND") - cliSbi := viper.GetString("CLI_SBI") - - if err := cli.HTTPGet( - testAPIEndpoint, - "addDevice", - "address="+testAddress, - "password="+testPassword, - "username="+testUsername, - "sbi="+cliSbi, - "pnd="+cliPnd, - ); (err != nil) != tt.wantErr { - t.Errorf("gosdn cli add-device error = %v, wantErr %v", err, tt.wantErr) - return - } - did := viper.GetString("LAST_DEVICE_UUID") - - if err := cli.HTTPGet( - testAPIEndpoint, - "request", - "uuid="+did, - "sbi="+cliSbi, - "pnd="+cliPnd, - "path=/system/config/hostname", - ); (err != nil) != tt.wantErr { - t.Errorf("gosdn cli request error = %v, wantErr %v", err, tt.wantErr) - return - } - - if err := cli.HTTPGet( - testAPIEndpoint, - "getDevice", - "address="+testAddress, - "uuid="+did, - "sbi="+cliSbi, - "pnd="+cliPnd, - ); (err != nil) != tt.wantErr { - t.Errorf("gosdn cli get-device error = %v, wantErr %v", err, tt.wantErr) - return - } - - hostname := guuid.New().String() - if err := cli.HTTPGet( - testAPIEndpoint, - "set", - "address="+testAddress, - "uuid="+did, - "sbi="+cliSbi, - "pnd="+cliPnd, - "path=/system/config/hostname", - "value="+hostname, - ); (err != nil) != tt.wantErr { - t.Errorf("gosdn cli set error = %v, wantErr %v", err, tt.wantErr) - return - } - - resp, err := cli.Get(testAddress, testUsername, testPassword, "/system/config/hostname") - if (err != nil) != tt.wantErr { - t.Errorf("cli.Get() error = %v, wantErr %v", err, tt.wantErr) - return - } - got := resp.Notification[0].Update[0].Val.GetStringVal() - if got != hostname { - t.Errorf("integration test failed = got: %v, want: %v", got, hostname) - } - }) - } -} diff --git a/test/integration/nucleusIntegration_test.go b/test/integration/nucleusIntegration_test.go index 816888d6f77f857225f34d22b794017efe641629..68ac907101bd4fb1dd82c2289821e820c9411030 100644 --- a/test/integration/nucleusIntegration_test.go +++ b/test/integration/nucleusIntegration_test.go @@ -1,96 +1,243 @@ package integration import ( - "code.fbi.h-da.de/cocsn/gosdn/forks/goarista/gnmi" - "code.fbi.h-da.de/cocsn/gosdn/nucleus" "context" - gpb "github.com/openconfig/gnmi/proto/gnmi" - pb "google.golang.org/protobuf/proto" + "os" "reflect" "sort" "testing" "time" + + "github.com/google/uuid" + + ppb "code.fbi.h-da.de/danet/api/go/gosdn/pnd" + spb "code.fbi.h-da.de/danet/api/go/gosdn/southbound" + tpb "code.fbi.h-da.de/danet/api/go/gosdn/transport" + "code.fbi.h-da.de/danet/gosdn/interfaces/change" + + "code.fbi.h-da.de/danet/forks/goarista/gnmi" + "code.fbi.h-da.de/danet/gosdn/nucleus" + "code.fbi.h-da.de/danet/gosdn/nucleus/errors" + "code.fbi.h-da.de/danet/gosdn/nucleus/types" + "code.fbi.h-da.de/danet/gosdn/nucleus/util/proto" + gpb "github.com/openconfig/gnmi/proto/gnmi" + log "github.com/sirupsen/logrus" + pb "google.golang.org/protobuf/proto" ) +const unreachable = "203.0.113.10:6030" +const testPath = "/system/config/hostname" + +var modifiedHostname = "ceos3000" +var testAddress = "141.100.70.170:6030" +var testUsername = "admin" +var testPassword = "arista" +var opt *tpb.TransportOption var gnmiMessages map[string]pb.Message -func TestGnmi_SetIntegration(t *testing.T) { +func TestMain(m *testing.M) { + testSetupIntegration() + os.Exit(m.Run()) +} + +func testSetupIntegration() { + if os.Getenv("GOSDN_LOG") == "nolog" { + log.SetLevel(log.PanicLevel) + } + + addr := os.Getenv("CEOS_TEST_ENDPOINT") + if addr != "" { + testAddress = addr + log.Infof("CEOS_TEST_ENDPOINT set to %v", testAddress) + } + u := os.Getenv("GOSDN_TEST_USER") + if u != "" { + testUsername = u + log.Infof("GOSDN_TEST_USER set to %v", testUsername) + } + p := os.Getenv("GOSDN_TEST_PASSWORD") + if p != "" { + testPassword = p + log.Infof("GOSDN_TEST_PASSWORD set to %v", testPassword) + } + + gnmiMessages = map[string]pb.Message{ + "../proto/cap-resp-arista-ceos": &gpb.CapabilityResponse{}, + "../proto/req-full-node": &gpb.GetRequest{}, + "../proto/req-full-node-arista-ceos": &gpb.GetRequest{}, + "../proto/req-interfaces-arista-ceos": &gpb.GetRequest{}, + "../proto/req-interfaces-interface-arista-ceos": &gpb.GetRequest{}, + "../proto/req-interfaces-wildcard": &gpb.GetRequest{}, + "../proto/resp-full-node": &gpb.GetResponse{}, + "../proto/resp-full-node-arista-ceos": &gpb.GetResponse{}, + "../proto/resp-interfaces-arista-ceos": &gpb.GetResponse{}, + "../proto/resp-interfaces-interface-arista-ceos": &gpb.GetResponse{}, + "../proto/resp-interfaces-wildcard": &gpb.GetResponse{}, + "../proto/resp-set-system-config-hostname": &gpb.SetResponse{}, + } + for k, v := range gnmiMessages { + if err := proto.Read(k, v); err != nil { + log.Fatalf("error parsing %v: %v", k, err) + } + } + + opt = &tpb.TransportOption{ + Address: testAddress, + Username: testUsername, + Password: testPassword, + TransportOption: &tpb.TransportOption_GnmiTransportOption{ + GnmiTransportOption: &tpb.GnmiTransportOption{}, + }, + } +} + +func TestGnmi_SetInvalidIntegration(t *testing.T) { if testing.Short() { t.Skip("skipping integration test") } type fields struct { - opt *nucleus.GnmiTransportOptions + opt *tpb.TransportOption } type args struct { - ctx context.Context - params []interface{} + ctx context.Context + payload change.Payload } tests := []struct { name string fields fields args args - want interface{} wantErr bool }{ { name: "destination unreachable", - fields: fields{opt: &nucleus.GnmiTransportOptions{ - Config: gnmi.Config{ - Addr: "203.0.113.10:6030", + fields: fields{ + opt: &tpb.TransportOption{ + Address: unreachable, + TransportOption: &tpb.TransportOption_GnmiTransportOption{ + GnmiTransportOption: &tpb.GnmiTransportOption{}}, }, }, - }, args: args{ - ctx: context.Background(), - params: []interface{}{&gnmi.Operation{}}, + ctx: context.Background(), + payload: change.Payload{}, }, - want: nil, wantErr: true, }, { - name: "valid update", + name: "invalid update", fields: fields{opt: opt}, args: args{ - ctx: context.Background(), - params: []interface{}{ - &gnmi.Operation{ - Type: "update", - Origin: "", - Target: "", - Path: []string{ - "system", - "config", - "hostname", - }, - Val: "ceos3000", - }, - }, + ctx: context.Background(), + payload: change.Payload{}, }, - want: gnmiMessages["../proto/resp-set-system-config-hostname"], - wantErr: false, + wantErr: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - g, err := nucleus.NewGnmiTransport(tt.fields.opt) + g, err := nucleus.NewTransport(tt.fields.opt, nucleus.NewSBI(spb.Type_OPENCONFIG)) if err != nil { t.Errorf("NewGnmiTransport() error = %v, wantErr %v", err, tt.wantErr) return } - resp, err := g.Set(tt.args.ctx, tt.args.params...) + err = g.Set(tt.args.ctx, tt.args.payload) if (err != nil) != tt.wantErr { t.Errorf("Set() error = %v, wantErr %v", err, tt.wantErr) return } - got, ok := resp.(*gpb.SetResponse) - if !ok { - t.Errorf("want: %v, got %v, error: %v", reflect.TypeOf(&gpb.SetResponse{}), reflect.TypeOf(resp), &nucleus.ErrInvalidTypeAssertion{}) + }) + } +} + +func TestGnmi_SetValidIntegration(t *testing.T) { + if testing.Short() { + t.Skip("skipping integration test") + } + + sbi := nucleus.NewSBI(spb.Type_OPENCONFIG) + opt := &tpb.TransportOption{ + Address: testAddress, + Username: testUsername, + Password: testPassword, + TransportOption: &tpb.TransportOption_GnmiTransportOption{ + GnmiTransportOption: &tpb.GnmiTransportOption{}, + }, + } + pnd, err := nucleus.NewPND("test", "test", uuid.New(), sbi, nil, nil) + if err != nil { + t.Error(err) + return + } + if err := pnd.AddDevice("test", opt, sbi.ID()); err != nil { + t.Error(err) + return + } + device, err := pnd.GetDevice("test") + if err != nil { + t.Error(err) + return + } + + tests := []struct { + name string + apiOp ppb.ApiOperation + path string + value string + want string + }{ + { + name: "update", + apiOp: ppb.ApiOperation_UPDATE, + path: testPath, + value: modifiedHostname, + want: modifiedHostname, + }, + { + name: "replace", + apiOp: ppb.ApiOperation_REPLACE, + path: "/system/config/domain-name", + value: modifiedHostname, + want: modifiedHostname, + }, + { + name: "delete", + apiOp: ppb.ApiOperation_DELETE, + path: testPath, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cuid, err := pnd.ChangeOND(device.ID(), tt.apiOp, tt.path, tt.value) + if err != nil { + t.Error(err) + return + } + if err := pnd.Commit(cuid); err != nil { + t.Error(err) + return } - if err != nil && tt.wantErr { + if err := pnd.Confirm(cuid); err != nil { + t.Error(err) return - } else if got.Prefix.Target != testAddress || - got.Response[0].Op != gpb.UpdateResult_UPDATE { - t.Errorf("Set() got = %v, want %v", got, tt.want) + } + if tt.name != "delete" { + resp, err := pnd.Request(device.ID(), tt.path) + if err != nil { + t.Error(err) + return + } + r, ok := resp.(*gpb.GetResponse) + if !ok { + t.Error(&errors.ErrInvalidTypeAssertion{ + Value: resp, + Type: &gpb.GetResponse{}, + }) + return + } + got := r.Notification[0].Update[0].Val.GetStringVal() + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("GetDevice() got = %v, want %v", got, tt.want) + } } }) } @@ -106,7 +253,7 @@ func TestGnmi_GetIntegration(t *testing.T) { "system/config/hostname", } type fields struct { - opt *nucleus.GnmiTransportOptions + opt *tpb.TransportOption } type args struct { ctx context.Context @@ -131,12 +278,13 @@ func TestGnmi_GetIntegration(t *testing.T) { }, { name: "destination unreachable", - fields: fields{opt: &nucleus.GnmiTransportOptions{ - Config: gnmi.Config{ - Addr: "203.0.113.10:6030", + fields: fields{ + opt: &tpb.TransportOption{ + Address: unreachable, + TransportOption: &tpb.TransportOption_GnmiTransportOption{ + GnmiTransportOption: &tpb.GnmiTransportOption{}}, }, }, - }, args: args{ ctx: context.Background(), params: paths, @@ -147,7 +295,7 @@ func TestGnmi_GetIntegration(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - g, err := nucleus.NewGnmiTransport(tt.fields.opt) + g, err := nucleus.NewTransport(tt.fields.opt, nucleus.NewSBI(spb.Type_OPENCONFIG)) if err != nil { t.Error(err) return @@ -169,7 +317,7 @@ func TestGnmi_SubscribeIntegration(t *testing.T) { } type fields struct { - opt *nucleus.GnmiTransportOptions + opt *tpb.TransportOption } type args struct { ctx context.Context @@ -184,9 +332,19 @@ func TestGnmi_SubscribeIntegration(t *testing.T) { { name: "default", fields: fields{ - opt: &nucleus.GnmiTransportOptions{ - Config: opt.Config, - RespChan: make(chan *gpb.SubscribeResponse), + opt: &tpb.TransportOption{ + Address: testAddress, + Username: testUsername, + Password: testPassword, + Tls: false, + TransportOption: &tpb.TransportOption_GnmiTransportOption{ + GnmiTransportOption: &tpb.GnmiTransportOption{ + Compression: "", + GrpcDialOptions: nil, + Token: "", + Encoding: 0, + }, + }, }, }, args: args{ @@ -208,9 +366,9 @@ func TestGnmi_SubscribeIntegration(t *testing.T) { { name: "wrong path", fields: fields{ - opt: &nucleus.GnmiTransportOptions{ - Config: opt.Config, - RespChan: make(chan *gpb.SubscribeResponse), + opt: &tpb.TransportOption{ + TransportOption: &tpb.TransportOption_GnmiTransportOption{ + GnmiTransportOption: &tpb.GnmiTransportOption{}}, }, }, args: args{ @@ -231,11 +389,10 @@ func TestGnmi_SubscribeIntegration(t *testing.T) { { name: "destination unreachable", fields: fields{ - opt: &nucleus.GnmiTransportOptions{ - Config: gnmi.Config{ - Addr: "203.0.113.10:6030", - }, - RespChan: make(chan *gpb.SubscribeResponse), + opt: &tpb.TransportOption{ + Address: "203.0.113.10:6030", + TransportOption: &tpb.TransportOption_GnmiTransportOption{ + GnmiTransportOption: &tpb.GnmiTransportOption{}}, }, }, args: args{ @@ -247,19 +404,19 @@ func TestGnmi_SubscribeIntegration(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { var wantErr = tt.wantErr - g, err := nucleus.NewGnmiTransport(tt.fields.opt) + g, err := nucleus.NewTransport(tt.fields.opt, nucleus.NewSBI(spb.Type_OPENCONFIG)) if err != nil { t.Error(err) return } - ctx := context.WithValue(context.Background(), nucleus.CtxKeyOpts, tt.args.opts) //nolint + ctx := context.WithValue(context.Background(), types.CtxKeyOpts, tt.args.opts) //nolint ctx, cancel := context.WithCancel(ctx) go func() { subErr := g.Subscribe(ctx) if (subErr != nil) != wantErr { if !wantErr && subErr != nil { if subErr.Error() != "rpc error: code = Canceled desc = context canceled" { - t.Errorf("Subscribe() error = %v, wantErr %v", err, tt.wantErr) + t.Errorf("Subscribe() error = %v, wantErr %v", subErr, tt.wantErr) } } } @@ -276,7 +433,7 @@ func TestGnmi_CapabilitiesIntegration(t *testing.T) { t.Skip("skipping integration test") } type fields struct { - opt *nucleus.GnmiTransportOptions + opt *tpb.TransportOption } type args struct { ctx context.Context @@ -311,10 +468,10 @@ func TestGnmi_CapabilitiesIntegration(t *testing.T) { }, { name: "destination unreachable", - fields: fields{opt: &nucleus.GnmiTransportOptions{ - Config: gnmi.Config{ - Addr: "203.0.113.10:6030", - }, + fields: fields{opt: &tpb.TransportOption{ + Address: "203.0.113.10:6030", + TransportOption: &tpb.TransportOption_GnmiTransportOption{ + GnmiTransportOption: &tpb.GnmiTransportOption{}}, }, }, args: args{ctx: context.Background()}, @@ -324,11 +481,18 @@ func TestGnmi_CapabilitiesIntegration(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - g, err := nucleus.NewGnmiTransport(tt.fields.opt) + tr, err := nucleus.NewTransport(tt.fields.opt, nucleus.NewSBI(spb.Type_OPENCONFIG)) if err != nil { t.Error(err) return } + g, ok := tr.(*nucleus.Gnmi) + if !ok { + t.Error(&errors.ErrInvalidTypeAssertion{ + Value: tr, + Type: &nucleus.Gnmi{}, + }) + } resp, err := g.Capabilities(tt.args.ctx) if (err != nil) != tt.wantErr { t.Errorf("Capabilities() error = %v, wantErr %v", err, tt.wantErr) diff --git a/test/targets.go b/test/targets.go index 309b818471b71581a3efe2ffa2bf65baf0b639b0..4a59a06812d5088cd7b2e279e1c941f13181d06a 100644 --- a/test/targets.go +++ b/test/targets.go @@ -1,8 +1,11 @@ package test import ( - "code.fbi.h-da.de/cocsn/gosdn/forks/google/gnmi" - oc "code.fbi.h-da.de/cocsn/yang-models/generated/arista" + "net" + "reflect" + + "code.fbi.h-da.de/danet/forks/google/gnmi" + oc "code.fbi.h-da.de/danet/yang-models/generated/arista" pb "github.com/openconfig/gnmi/proto/gnmi" "github.com/openconfig/goyang/pkg/yang" "github.com/openconfig/ygot/util" @@ -10,8 +13,6 @@ import ( log "github.com/sirupsen/logrus" "google.golang.org/grpc" "google.golang.org/grpc/reflection" - "net" - "reflect" ) type server struct { diff --git a/test/terraform/containers.tf b/test/terraform/containers.tf index 4149322318193d0644f0e8f3eefafff44681a2ec..c735846a7bd7fe17467620e1887c5d6e2ae56283 100644 --- a/test/terraform/containers.tf +++ b/test/terraform/containers.tf @@ -6,12 +6,8 @@ resource "docker_container" "gosdn" { restart = "always" networks_advanced { - name = "bridge" - } - - ports { - internal = 8080 - external = 8080 + name = "ci" + ipv4_address = var.gosdn_address } } @@ -22,13 +18,9 @@ resource "docker_container" "ceos" { image = docker_image.ceos.name restart = "always" - ports { - internal = 6030 - external = 6030 - } - networks_advanced { - name = "bridge" + name = "ci" + ipv4_address = var.ceos_address } command = ["/sbin/init", diff --git a/test/terraform/images.tf b/test/terraform/images.tf index 39d234b387f5b14a704a028b6b7f31f39a217218..990cf0efdebee846ae4b7fb688c9abd27eb1c0b6 100644 --- a/test/terraform/images.tf +++ b/test/terraform/images.tf @@ -3,5 +3,5 @@ resource "docker_image" "gosdn" { } resource "docker_image" "ceos" { - name = "registry.code.fbi.h-da.de/cocsn/gosdn/ceos:latest" + name = var.ceos_tag } \ No newline at end of file diff --git a/test/terraform/main.tf b/test/terraform/main.tf index 1f228766349903fbad196dbd3b1df05324f8c70b..a08c19bb698658ed2430433851e02cbca39a8782 100644 --- a/test/terraform/main.tf +++ b/test/terraform/main.tf @@ -1,6 +1,7 @@ terraform { backend "http" { } + required_providers { docker = { source = "kreuzwerker/docker" diff --git a/test/terraform/networks.tf b/test/terraform/networks.tf deleted file mode 100644 index 2372a310a9d9c239419a706a22ffc809fb05a64a..0000000000000000000000000000000000000000 --- a/test/terraform/networks.tf +++ /dev/null @@ -1,15 +0,0 @@ -resource "docker_network" "danet_legacy" { - name = "legacy-${random_id.server.hex}" - - ipam_config { - subnet = "172.100.100.0/24" - } -} - -resource "docker_network" "danet" { - name = "danet-${random_id.server.hex}" - ipv6 = true - ipam_config { - subnet = "fdfe::/64" - } -} \ No newline at end of file diff --git a/test/terraform/resources.tf b/test/terraform/resources.tf index 9659f2d949aaa978b04167a7a62d1a0dcc6752eb..d5f2938f3e0d7e215d339c21dd486d36de57a3bc 100644 --- a/test/terraform/resources.tf +++ b/test/terraform/resources.tf @@ -1,3 +1,3 @@ resource "random_id" "server" { byte_length = 8 -} +} \ No newline at end of file diff --git a/test/terraform/variables.tf b/test/terraform/variables.tf index beacac0158789901783dad04be71645d0cb2a697..88bd132cfd46fe5009e504bbdbbbe5455260ecaf 100644 --- a/test/terraform/variables.tf +++ b/test/terraform/variables.tf @@ -9,6 +9,7 @@ variable "integration_username" { variable "integration_access_token" { type = string } + variable "tls_key" { type = string } @@ -23,10 +24,23 @@ variable "tls_ca_cert" { variable "container_tag" { type = string - default = "registry.code.fbi.h-da.de/cocsn/gosdn:latest" + default = "registry.code.fbi.h-da.de/danet/gosdn:latest" +} + +variable "ceos_tag" { + type = string + default = "registry.code.fbi.h-da.de/danet/gosdn/ceos:latest" } variable "network_name" { type = string default = "" +} + +variable "ceos_address" { + type = string +} + +variable "gosdn_address" { + type = string } \ No newline at end of file