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 [![coverage report](https://code.fbi.h-da.de/cocsn/gosdn/badges/master/coverage.svg)](https://code.fbi.h-da.de/cocsn/gosdn/-/commits/master) [![pipeline status](https://code.fbi.h-da.de/cocsn/gosdn/badges/master/pipeline.svg)](https://code.fbi.h-da.de/cocsn/gosdn/-/commits/master)
+# goSDN [![coverage report](https://code.fbi.h-da.de/danet/gosdn/badges/master/coverage.svg)](https://code.fbi.h-da.de/danet/gosdn/-/commits/master) [![pipeline status](https://code.fbi.h-da.de/danet/gosdn/badges/master/pipeline.svg)](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
-
-[![asciicast](https://asciinema.org/a/dfrDlFQt5DPlG9HDyetdmeEW8.svg)](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 |
 | ------ | ------ |
-| [![coverage report](https://code.fbi.h-da.de/cocsn/gosdn/badges/master/coverage.svg)](https://code.fbi.h-da.de/cocsn/gosdn/-/commits/master) | [![coverage report](https://code.fbi.h-da.de/cocsn/gosdn/badges/develop/coverage.svg)](https://code.fbi.h-da.de/cocsn/gosdn/-/commits/develop) |
-| [![pipeline status](https://code.fbi.h-da.de/cocsn/gosdn/badges/master/pipeline.svg)](https://code.fbi.h-da.de/cocsn/gosdn/-/commits/master) | [![pipeline status](https://code.fbi.h-da.de/cocsn/gosdn/badges/develop/pipeline.svg)](https://code.fbi.h-da.de/cocsn/gosdn/-/commits/develop) |
+| [![coverage report](https://code.fbi.h-da.de/danet/gosdn/badges/master/coverage.svg)](https://code.fbi.h-da.de/danet/gosdn/-/commits/master) | [![coverage report](https://code.fbi.h-da.de/danet/gosdn/badges/develop/coverage.svg)](https://code.fbi.h-da.de/danet/gosdn/-/commits/develop) |
+| [![pipeline status](https://code.fbi.h-da.de/danet/gosdn/badges/master/pipeline.svg)](https://code.fbi.h-da.de/danet/gosdn/-/commits/master) | [![pipeline status](https://code.fbi.h-da.de/danet/gosdn/badges/develop/pipeline.svg)](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