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 78d4fbdd29dfd13411968c8f050bac9b732ed7d7..8929b266e9bf9595876b07316bcbade972de6e72 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,34 +1,24 @@
 variables:
-  SECURE_ANALYZERS_PREFIX: registry.gitlab.com/gitlab-org/security-products/analyzers
-  DOCKER_IMAGE_SHA: ${CI_REGISTRY_IMAGE}:${CI_COMMIT_SHA}
-
-workflow:
-  rules:
-    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
-    - if: '$CI_PIPELINE_SOURCE == "schedule"'
-    - if: '$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH != "develop" && $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH'
-      when: never
-    - if: '$CI_COMMIT_BRANCH'
+  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
   - 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/.containerlab-ci.yml'
-  - local: '/build/ci/.uml-autogen-ci.yml'
-  - local: '/build/ci/.deploy-k8s.yml'
-
+  - 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 89%
rename from build/ci/.deploy-k8s.yml
rename to .gitlab/ci/.deploy-k8s.yml
index 8f3458606261bff2f0c39a45eacfa20b2062d06f..e2d8e52baae3834784bfd8cbe1a36f38d699b3bd 100644
--- a/build/ci/.deploy-k8s.yml
+++ b/.gitlab/ci/.deploy-k8s.yml
@@ -1,6 +1,6 @@
 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
@@ -14,7 +14,7 @@ build:k8s-bot:
 
 .deploy: &deploy
   image: 
-    name: bitnami/kubectl:latest
+    name: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/bitnami/kubectl:latest
     entrypoint: [""]
   before_script:
     - echo "override global before script"
diff --git a/build/ci/.golangci-config/.golangci.yml b/.gitlab/ci/.golangci-config/.golangci.yml
similarity index 89%
rename from build/ci/.golangci-config/.golangci.yml
rename to .gitlab/ci/.golangci-config/.golangci.yml
index 1a2b9183717c0c1a95b8782e15a5189ee2059c10..e9ea64defdbb908d5d1892ff7f8351aaa6cc7a6a 100644
--- a/build/ci/.golangci-config/.golangci.yml
+++ b/.gitlab/ci/.golangci-config/.golangci.yml
@@ -27,9 +27,13 @@ linters:
   enable:
     - gofmt
     - goimports
-    - revive 
     - gocyclo
     - govet
+    - unused
+    - staticcheck
+    - typecheck
+    - revive
+    - whitespace
 issues:
   exclude-use-default: false
   max-issues-per-linter: 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/build/ci/.uml-autogen-ci.yml b/.gitlab/ci/.uml-autogen-ci.yml
similarity index 92%
rename from build/ci/.uml-autogen-ci.yml
rename to .gitlab/ci/.uml-autogen-ci.yml
index 28ee54f267fe971524185099089dcffde1a07cca..adaf8c99dc09056b5183d0177e7c3e7dfaf6a5b3 100644
--- a/build/ci/.uml-autogen-ci.yml
+++ b/.gitlab/ci/.uml-autogen-ci.yml
@@ -1,5 +1,5 @@
 goplantuml:
-    image: golang:1.14
+    image: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/golang:$GOLANG_VERSION
     stage: .post
     only:
         - develop
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/build/ci/generate_octet.sh b/.gitlab/ci/scripts/generate_octet.sh
similarity index 93%
rename from build/ci/generate_octet.sh
rename to .gitlab/ci/scripts/generate_octet.sh
index 6cad5addc30badad963ee2e9d6dfe4f96fdc6aad..9d5dce7312a7ab516bd01d208ac961d5e23fe955 100755
--- a/build/ci/generate_octet.sh
+++ b/.gitlab/ci/scripts/generate_octet.sh
@@ -10,4 +10,4 @@ decimal_value=${decimal_value/-/}
 
 octet=$(((decimal_value % 255)))
 
-echo -n $octet
\ No newline at end of file
+echo -n $octet
diff --git a/build/ci/wait-for-it.sh b/.gitlab/ci/scripts/wait-for-it.sh
similarity index 100%
rename from build/ci/wait-for-it.sh
rename to .gitlab/ci/scripts/wait-for-it.sh
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 5048df503bd2917698d45b5aa385138b1789c149..0e9227f3eb32885934ca7c235d988624df538d27 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,11 +1,8 @@
-FROM golang:1.16-buster AS installer
-ARG GITLAB_USER
-ARG GITLAB_TOKEN
+ARG GOLANG_VERSION=1.17
 ARG BUILDARGS
+ARG $GITLAB_PROXY
 
-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"
-RUN go env -w GOPRIVATE=code.fbi.h-da.de/*
+FROM ${GITLAB_PROXY}golang:$GOLANG_VERSION-buster AS installer
 
 WORKDIR /src/gosdn
 COPY go.* ./
@@ -13,20 +10,11 @@ RUN go mod download
 
 FROM installer as builder
 
-
-COPY ./api ./api
-COPY ./build ./build
-COPY ./cmd ./cmd
-COPY ./cli ./cli
-COPY ./configs ./configs
-COPY ./database ./database
-COPY ./mocks ./mocks
-COPY ./nucleus ./nucleus
-COPY ./test ./test
+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 .
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 3d946b9e6a6df911abaa7f96c2bfd90a2376ef24..0cf06d1d7382c229d3d5c24891a014528452e118 100644
--- a/README.md
+++ b/README.md
@@ -64,11 +64,8 @@ We have an instance of `goSDN` for each the latest master and current develop br
 
 ## 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
 
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 90ae33aefb71a0a8bae15b0d3dbf3d889ec38718..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/danet/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 633d30f09222872df4f1da39689ace99a269d07b..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/danet/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 d1df2bc92a1ae6577eb001528ab3723b37c98844..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/danet/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 0d998529954dbcbb1cf4e775ccfa944dcf4e9075..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/danet/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 b1f3168fc0daeed5af80b526546bae8ebf1ec02a..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/danet/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 a45eab05e9aa2f515a0f9baff7ec64c3d876e91b..0000000000000000000000000000000000000000
--- a/build/cd/deploy.go
+++ /dev/null
@@ -1,383 +0,0 @@
-package main
-
-import (
-	"context"
-	"os"
-	"strconv"
-
-	"code.fbi.h-da.de/danet/gosdn/nucleus"
-	log "github.com/sirupsen/logrus"
-	"github.com/spf13/viper"
-	appv1 "k8s.io/api/apps/v1"
-	corev1 "k8s.io/api/core/v1"
-	"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"
-)
-
-// GRPC defines the grpc port used by the deployment
-const GRPC = 55055
-
-// HTTP defines the http port used by the deployment
-const HTTP = 8080
-
-var service *corev1.Service
-var deployment *appv1.Deployment
-var config *corev1.ConfigMap
-
-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("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)
-		}
-	case "getenv":
-		if err := getenv(clientset, tag); err != nil {
-			log.Fatal(err)
-		}
-	default:
-		log.Fatal("invalid option")
-	}
-}
-
-func getenv(clientset *kubernetes.Clientset, tag string) error {
-	env := "gosdn-" + tag
-	opts := metav1.GetOptions{}
-	ctx := context.Background()
-	service, err := clientset.CoreV1().Services("cocsn").Get(ctx, env, opts)
-	if err != nil {
-		return err
-	}
-	var ip string
-	for _, ingress := range service.Status.LoadBalancer.Ingress {
-		ip = ingress.IP
-	}
-
-	var port string
-	for _, p := range service.Spec.Ports {
-		if p.Name == "grpc" {
-			port = strconv.Itoa(int(p.NodePort))
-		}
-	}
-	log.WithFields(log.Fields{
-		"ip":   ip,
-		"port": port,
-	}).Info(env)
-	viper.Set("GOSDN_TEST_API_ENDPOINT", ip+":"+port)
-	return viper.SafeWriteConfigAs(".k8s.toml")
-}
-
-// nolint
-func create(clientset *kubernetes.Clientset, tag string) error {
-	env := "gosdn-" + tag
-	deployment = createDeployment(env, tag)
-	opts := metav1.CreateOptions{}
-	ctx := context.Background()
-
-	_, 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)
-	}
-	deployment, err = clientset.AppsV1().Deployments("cocsn").Get(ctx, env, metav1.GetOptions{})
-	if err != nil {
-		log.Error(err)
-	}
-
-	config = createConfigMap(env)
-	_, 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)
-	}
-
-	service = createService(env)
-	_, 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)
-	}
-	return nil
-}
-
-func update(clientset *kubernetes.Clientset, resource metav1.Common, env string) error {
-	opts := metav1.UpdateOptions{}
-	getOpts := metav1.GetOptions{}
-	ctx := context.Background()
-	switch resource := resource.(type) {
-	case *corev1.Service:
-		service := resource
-		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 *corev1.ConfigMap:
-		config := resource
-		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
-		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)
-	}
-	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},
-			OwnerReferences: []metav1.OwnerReference{
-				{
-					APIVersion: "v1",
-					Kind:       "Deployment",
-					Name:       environment,
-					UID:        deployment.GetUID(),
-				},
-			},
-		},
-		Spec: corev1.ServiceSpec{
-			Ports: []corev1.ServicePort{
-				{
-					Name:       "http",
-					Port:       HTTP,
-					TargetPort: intstr.IntOrString{IntVal: HTTP},
-				},
-				{
-					Name:       "grpc",
-					Port:       GRPC,
-					TargetPort: intstr.IntOrString{IntVal: GRPC},
-				},
-			},
-			Selector: map[string]string{"run": environment},
-			Type:     "LoadBalancer",
-		},
-	}
-}
-
-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/danet/gosdn:" + hash,
-							Command:    nil,
-							Args:       nil,
-							WorkingDir: "",
-							Ports: []corev1.ContainerPort{
-								{
-									Name:          "grpc",
-									ContainerPort: GRPC,
-								},
-								{
-									Name:          "http",
-									ContainerPort: HTTP,
-								},
-							},
-							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: HTTP},
-									},
-								},
-								InitialDelaySeconds: 5,
-								PeriodSeconds:       2,
-							},
-							ReadinessProbe: &corev1.Probe{
-								Handler: corev1.Handler{
-									HTTPGet: &corev1.HTTPGetAction{
-										Path: "/readyz",
-										Port: intstr.IntOrString{IntVal: HTTP},
-									},
-								},
-								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",
-			OwnerReferences: []metav1.OwnerReference{
-				{
-					APIVersion: "v1",
-					Kind:       "Deployment",
-					Name:       env,
-					UID:        deployment.GetUID(),
-				},
-			},
-		},
-		Data: map[string]string{"gosdn.toml": "#empty"},
-	}
-}
diff --git a/build/ci/.build-container.yml b/build/ci/.build-container.yml
deleted file mode 100644
index e1e6107d56fe9a6a1f14491641da3bfd9a72f83a..0000000000000000000000000000000000000000
--- a/build/ci/.build-container.yml
+++ /dev/null
@@ -1,43 +0,0 @@
-variables:
-  DOCKER_TLS_CERTDIR: "/certs"
-
-build-docker:
-  before_script:
-    - echo "override global before script"
-  stage: build
-  allow_failure: false
-  needs: []
-  tags:
-    - shell-builder
-
-  rules:
-    - if: $CI_COMMIT_BRANCH == "develop" && $CI_NIGHTLY == null
-      variables:
-        TAG: $CI_REGISTRY_IMAGE:develop
-        BUILDARGS: -race
-    - if: $CI_NIGHTLY == "develop"
-      variables:
-        TAG: $CI_REGISTRY_IMAGE:nightly-develop
-        BUILDARGS: -race
-    - if: $CI_NIGHTLY == "mainline"
-      variables:
-        TAG: $CI_REGISTRY_IMAGE:nightly
-    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
-      variables:
-        TAG: $CI_REGISTRY_IMAGE:merge-request
-        BUILDARGS: -race
-    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_NIGHTLY == null
-      variables:
-        TAG: $CI_REGISTRY_IMAGE:latest
-    - if: '$CI_COMMIT_BRANCH'
-      variables:
-        TAG: $CI_REGISTRY_IMAGE:branch
-      
-  script:
-   - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
-   - 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 push $DOCKER_IMAGE_SHA
-   - docker tag $DOCKER_IMAGE_SHA $TAG
-   - docker push $TAG
-   - docker build --target installer --build-arg GITLAB_USER=$GO_MODULES_USER --build-arg GITLAB_TOKEN=$GO_MODULES_ACCESS_TOKEN --build-arg BUILDARGS=$BUILDARGS -t ${CI_REGISTRY_IMAGE}:testing_${CI_PIPELINE_ID} .
-   - docker push ${CI_REGISTRY_IMAGE}:testing_${CI_PIPELINE_ID}
diff --git a/build/ci/.code-quality-ci.yml b/build/ci/.code-quality-ci.yml
deleted file mode 100644
index a608dd15e896e417aa25e19ee8657c037aa3e75e..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
diff --git a/build/ci/.containerlab-ci.yml b/build/ci/.containerlab-ci.yml
deleted file mode 100644
index 9a06ec3b3aaf9e63b8f9f153126bb46e67b428c4..0000000000000000000000000000000000000000
--- a/build/ci/.containerlab-ci.yml
+++ /dev/null
@@ -1,82 +0,0 @@
-variables:
-  CEOS_CONTAINER_IMAGE: "$CI_REGISTRY_IMAGE/ceos:latest"
-  CLAB_INT1_TEMPLATE: "${CI_PROJECT_DIR}/test/containerlab/int01.clab.yml"
-  CLAB_NAME: "clab${CI_PIPELINE_IID}"
-  CLAB_DIR: "/mnt"
-
-
-.containerlab_rules: &containerlab_rules
-  rules:
-    - if: $CI_PIPELINE_SOURCE == "merge_request_event" && ($CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == 'develop')
-    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
-    - if: $CI_NIGHTLY
-
-
-containerlab:template:
-  extends: .containerlab_rules
-  image: alpine:latest
-  stage: build
-  before_script:
-    - echo "Override global before_script"
-  script:
-    - ./build/ci/generate_octet.sh $CI_COMMIT_SHA >> $(pwd)/firstOctet
-    - ./build/ci/generate_octet.sh $CI_PIPELINE_ID >> $(pwd)/secondOctet
-    - export firstOctet=$(cat $(pwd)/firstOctet)
-    - export secondOctet=$(cat $(pwd)/secondOctet)
-    - export CLAB_MGMT_SUBNET="172.$firstOctet.$secondOctet.0/24"
-    - |
-      sed -e "s|@@CEOS_CONTAINER_IMAGE@@|${CEOS_CONTAINER_IMAGE}|g" \
-          -e "s|@@GOSDN_CONTAINER_IMAGE@@|${DOCKER_IMAGE_SHA}|g" \
-          -e "s|@@CLAB_NAME@@|${CLAB_NAME}|g" \
-          -e "s|@@CLAB_MGMT_SUBNET@@|${CLAB_MGMT_SUBNET}|g" \
-          ${CLAB_INT1_TEMPLATE} > ${CI_PROJECT_DIR}/${CLAB_NAME}.clab.yml
-    - cat ${CLAB_NAME}.clab.yml
-  artifacts:
-    name: ${CLAB_NAME}
-    paths:
-      - ${CI_PROJECT_DIR}/${CLAB_NAME}.clab.yml
-
-containerlab:deploy:
-  extends:
-    - .containerlab_rules
-  stage: apply
-  needs: ["containerlab:template", "build-docker"]
-  tags:
-    - shell
-  before_script:
-    - cd ${CLAB_DIR}
-    - echo "$CI_REGISTRY_PASSWORD" | docker login -u $CI_REGISTRY_USER --password-stdin $CI_REGISTRY
-    - echo $DOCKER_IMAGE_SHA
-    - docker pull $DOCKER_IMAGE_SHA
-    - docker pull ${CEOS_CONTAINER_IMAGE}
-  script:
-    - sudo containerlab deploy --topo ${CI_PROJECT_DIR}/${CLAB_NAME}.clab.yml --reconfigure
-    - echo "GOSDN_HTTP_PORT=$(docker inspect -f '{{ (index (index .NetworkSettings.Ports "8080/tcp") 0).HostPort }}' clab-${CLAB_NAME}-gosdn)" >> ${CI_PROJECT_DIR}/build.env
-    - echo "GOSDN_GRPC_PORT=$(docker inspect -f '{{ (index (index .NetworkSettings.Ports "55055/tcp") 0).HostPort }}' clab-${CLAB_NAME}-gosdn)" >> ${CI_PROJECT_DIR}/build.env
-    - echo "CEOS1_PORT=$(docker inspect -f '{{ (index (index .NetworkSettings.Ports "6030/tcp") 0).HostPort }}' clab-${CLAB_NAME}-ceos1)" >> ${CI_PROJECT_DIR}/build.env
-  dependencies:
-    - containerlab:template
-  artifacts:
-    reports:
-      dotenv: ${CI_PROJECT_DIR}/build.env
-
-containerlab:destroy:
-  rules:
-    - if: $CI_PIPELINE_SOURCE == "merge_request_event" && ($CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == 'develop')
-      when: always
-    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
-      when: always
-    - if: $CI_NIGHTLY
-      when: always
-  stage: .post
-  tags:
-    - shell
-  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 ${DOCKER_IMAGE_SHA}
-  allow_failure: true
-  dependencies:
-    - containerlab:template
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 f570e0efa1fb6d0ded192f9808a5bd38dca38f62..0000000000000000000000000000000000000000
--- a/build/ci/.test.yml
+++ /dev/null
@@ -1,47 +0,0 @@
-.integration-test: &integration-test
-  image: ${CI_REGISTRY_IMAGE}:testing_${CI_PIPELINE_ID}
-  stage: integration-test
-  needs:
-    - job: "containerlab:deploy"
-  variables:
-    GOSDN_LOG: "nolog"
-    GOSDN_TEST_API_ENDPOINT: "141.100.70.178:${GOSDN_GRPC_PORT}"
-    GOSDN_TEST_ENDPOINT: "141.100.70.178:${CEOS1_PORT}"
-    GOSDN_TEST_USER: "admin"
-    GOSDN_TEST_PASSWORD: "admin"
-  rules:
-    - if: $CI_NIGHTLY
-    - if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH
-    - if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME != $CI_DEFAULT_BRANCH
-      allow_failure: true
-
-integration-test:nucleus:
-  <<: *integration-test
-  script:
-    - ${CI_PROJECT_DIR}/build/ci/wait-for-it.sh ${GOSDN_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
-
-.test: &test
-  image: ${CI_REGISTRY_IMAGE}:testing_${CI_PIPELINE_ID}
-  stage: test
-  allow_failure: true
-  variables:
-    GOSDN_LOG: "nolog"
-    GOSDN_CHANGE_TIMEOUT: "100ms"
-  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
-
-unit-test:
-  script:
-    - go test -short -race $(go list ./... | grep -v /forks/ | grep -v /mocks ) -v -coverprofile=coverage.out
-  after_script:
-    - go tool cover -func=coverage.out
-  <<: *test
diff --git a/build/ci/generate_octet.bash b/build/ci/generate_octet.bash
deleted file mode 100755
index 8becfc98b0c47025b445f7216ee935d37b2e4c88..0000000000000000000000000000000000000000
--- a/build/ci/generate_octet.bash
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/bin/bash
-
-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
\ No newline at end of file
diff --git a/cli/capabilities.go b/cli/capabilities.go
deleted file mode 100644
index 56b50a156d79332f8fa633e6bed9192553473120..0000000000000000000000000000000000000000
--- a/cli/capabilities.go
+++ /dev/null
@@ -1,45 +0,0 @@
-package cli
-
-import (
-	"context"
-	"fmt"
-	"strings"
-
-	"code.fbi.h-da.de/danet/forks/goarista/gnmi"
-	"code.fbi.h-da.de/danet/gosdn/nucleus"
-	gpb "github.com/openconfig/gnmi/proto/gnmi"
-)
-
-// 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 e32b28d57a5764328f39e017dd5f89608bfdf1cf..0000000000000000000000000000000000000000
--- a/cli/get.go
+++ /dev/null
@@ -1,38 +0,0 @@
-package cli
-
-import (
-	"context"
-
-	"code.fbi.h-da.de/danet/forks/goarista/gnmi"
-	"code.fbi.h-da.de/danet/gosdn/nucleus"
-	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 0596a2cfdb1353d852f201a0a5922d3414acbb66..0000000000000000000000000000000000000000
--- a/cli/init.go
+++ /dev/null
@@ -1,17 +0,0 @@
-package cli
-
-import (
-	model "code.fbi.h-da.de/danet/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 cf0b844ce90e627a8d1eae81b3a2959ab30f3509..0000000000000000000000000000000000000000
--- a/cli/set.go
+++ /dev/null
@@ -1,51 +0,0 @@
-package cli
-
-import (
-	"context"
-	"os"
-
-	"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/util/proto"
-	pb "google.golang.org/protobuf/proto"
-)
-
-// 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 d44b9822c075aeb51b0df6b0dab3df3688e00621..0000000000000000000000000000000000000000
--- a/cli/subscribe.go
+++ /dev/null
@@ -1,61 +0,0 @@
-package cli
-
-import (
-	"context"
-	"fmt"
-	"os"
-	"os/signal"
-	"syscall"
-	"time"
-
-	"code.fbi.h-da.de/danet/forks/goarista/gnmi"
-	"code.fbi.h-da.de/danet/gosdn/nucleus"
-	gpb "github.com/openconfig/gnmi/proto/gnmi"
-	log "github.com/sirupsen/logrus"
-)
-
-// 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 e906b51735b9e395d182e8042ea646dae92bed91..0000000000000000000000000000000000000000
--- a/cli/target.go
+++ /dev/null
@@ -1,93 +0,0 @@
-package cli
-
-import (
-	"context"
-	"net"
-	"reflect"
-
-	"code.fbi.h-da.de/danet/forks/google/gnmi"
-	oc "code.fbi.h-da.de/danet/yang-models/generated/openconfig"
-	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"
-)
-
-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")
-	return g.Serve(listen)
-}
diff --git a/cmd/addDevice.go b/cmd/addDevice.go
deleted file mode 100644
index ffcac11cbed59ae1a3ddf1c26097aa443bb1acc0..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/danet/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 3daa5450911902c06b15a051f54edf67680e6b76..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/danet/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 930746b16dcecd37827171fda87b4acfa2b18f2a..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/danet/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 ab6db3561651309f60ccbc1524d0559c2c83461d..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/danet/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 2364162eed06fdf3aade32d866832e3e6935dd20..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/danet/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 7a48c44b5ee9e1fb94a0cd310a38588378ec8d97..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/danet/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 0fa22dce52e4cdd27807ef72fa6e29b218a4320c..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/danet/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/init.go b/cmd/init.go
deleted file mode 100644
index 1b40b8ecfb1981c6aff3d11f3607513f5a350897..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/danet/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 62cbcb0612d16bd5a88d5a1ea2702a443ebae700..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/danet/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 5fac9ec727efe8e5d60a0fd8ed74bad8404ee73f..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/danet/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 e66b0ced378972aee205acacfd266669065c8400..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/danet/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 249c5c78253883c3bddb38f72e6cadab7dfa1f0a..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/danet/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 c2cbe756b7ca82977338ee5a6b9db6418ee1e694..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/danet/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 c36654b0a042fffb90fb8dfc722d7a163860fe0f..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/danet/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 3ea5ddd50a2706cee1931690323d4e06b9a3d17c..0000000000000000000000000000000000000000
--- a/cmd/util.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"
-)
-
-// 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 86dbdb186b2114a590d74cfa26d2e99ff19990e9..0000000000000000000000000000000000000000
--- a/database/client.go
+++ /dev/null
@@ -1,360 +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/go.mod b/go.mod
index 8de7329e317e249c9679ca91aea338e32000838d..094fad6678d5b4f509352d45e740fb669f42bba8 100644
--- a/go.mod
+++ b/go.mod
@@ -1,24 +1,57 @@
 module code.fbi.h-da.de/danet/gosdn
 
-go 1.14
+go 1.17
 
 require (
-	code.fbi.h-da.de/danet/forks/goarista v0.0.0-20210709155912-0f86da96826a
-	code.fbi.h-da.de/danet/forks/google v0.0.0-20210709155912-0f86da96826a
-	code.fbi.h-da.de/danet/yang-models v0.0.8
-	github.com/golang/protobuf v1.5.2
-	github.com/google/uuid v1.1.2
-	github.com/neo4j/neo4j-go-driver v1.8.3
-	github.com/openconfig/gnmi v0.0.0-20210707145734-c69a5df04b53
-	github.com/openconfig/goyang v0.2.7
-	github.com/openconfig/ygot v0.11.2
+	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.1
-	github.com/spf13/viper v1.7.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.39.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
+	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 287ca78a2e6b584bf2397d69319530ef00948187..427cfd8f8a6f4ec2f16ff2a17b223137b7ebfbdb 100644
--- a/go.sum
+++ b/go.sum
@@ -9,46 +9,62 @@ 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/danet/forks/goarista v0.0.0-20210709155912-0f86da96826a h1:8oCdRLBesDxDcRW6F3Am579XXqXGrI6VZjKTmKuIRio=
-code.fbi.h-da.de/danet/forks/goarista v0.0.0-20210709155912-0f86da96826a/go.mod h1:uVe3gCeF2DcIho8K9CIO46uAkHW/lUF+fAaUX1vHrF0=
-code.fbi.h-da.de/danet/forks/google v0.0.0-20210709155912-0f86da96826a h1:zVrToJ2od/ORkgnPP8ezzPJGPF4/SUBDbtWuNS74zrg=
-code.fbi.h-da.de/danet/forks/google v0.0.0-20210709155912-0f86da96826a/go.mod h1:Uutdj5aA3jpzfNm3C8gt2wctYE6cRrdyZsILUgJ+tMY=
-code.fbi.h-da.de/danet/yang-models v0.0.8 h1:LuKt58Zh2mDkQa9s4hFaIANtZLxES7EFX1rIczD0GDs=
-code.fbi.h-da.de/danet/yang-models v0.0.8/go.mod h1:aoz0hgHZoEm2Apu9kA93g9nIBjAApBvx4pMFj2gbx9g=
+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.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=
@@ -68,13 +84,14 @@ github.com/aristanetworks/splunk-hec-go v0.3.3/go.mod h1:1VHO9r17b0K7WmOlLb9nTk/
 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/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/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
 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=
@@ -83,7 +100,9 @@ github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QH
 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=
@@ -102,6 +121,7 @@ github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee
 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=
@@ -115,10 +135,10 @@ 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=
@@ -128,8 +148,6 @@ github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5m
 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/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
-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/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=
@@ -139,18 +157,17 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m
 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/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=
@@ -161,26 +178,18 @@ github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgO
 github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
 github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
-github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
-github.com/go-logr/logr 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-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=
@@ -192,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=
@@ -206,6 +219,7 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD
 github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
 github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
 github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
+github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
 github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
 github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
 github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
@@ -222,33 +236,43 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
 github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
 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.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
 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=
@@ -258,7 +282,6 @@ github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+
 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=
@@ -267,14 +290,19 @@ github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t
 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=
@@ -288,14 +316,15 @@ 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=
@@ -312,16 +341,15 @@ github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX
 github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
 github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
 github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
-github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
 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.10.10/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
@@ -343,7 +371,6 @@ github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfn
 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=
@@ -353,18 +380,26 @@ github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-b
 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=
@@ -372,19 +407,16 @@ 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/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
-github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
 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=
@@ -392,49 +424,44 @@ github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzE
 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/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/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/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
-github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 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/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/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-20210707145734-c69a5df04b53 h1:xT/AVinvSf+uP/amEFrU1JJYBZXqikEyNtBPnfyefoE=
+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/go.mod h1:vX61x01Q46AzbZUzG617vWqh/cB+aisc+RrNkXRd3W8=
 github.com/openconfig/goyang v0.2.5/go.mod h1:vX61x01Q46AzbZUzG617vWqh/cB+aisc+RrNkXRd3W8=
-github.com/openconfig/goyang v0.2.7 h1:bWvqXzNekiyHR2eoNE1DWrS3zSQS3aNKl6V+BLQSRSU=
 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/go.mod h1:oCQNdXnv7dWc8scTDgoFkauv1wwplJn5HspHcjlxSAQ=
 github.com/openconfig/ygot v0.10.4/go.mod h1:oCQNdXnv7dWc8scTDgoFkauv1wwplJn5HspHcjlxSAQ=
-github.com/openconfig/ygot v0.11.2 h1:J5HTV1BtNZoc8LHDUpgA33rhccEIds81S32G2qgIDJY=
 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=
@@ -449,10 +476,10 @@ github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FI
 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/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/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
 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=
@@ -466,18 +493,21 @@ github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZ
 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.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=
@@ -486,6 +516,7 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8
 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=
@@ -494,6 +525,7 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT
 github.com/prometheus/procfs v0.0.8/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-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
@@ -503,6 +535,7 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L
 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=
@@ -514,34 +547,34 @@ github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrf
 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/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 h1:KfztREH0tPxJJ+geloSLaAkaPkr4ki2Er5quFV1TDo4=
 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=
@@ -574,42 +607,54 @@ github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMx
 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-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/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 h1:/ZScEX8SfEmUGRHs0gxpqteO5nfNW6axyZbBdw9A12g=
 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=
@@ -632,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=
@@ -640,6 +687,9 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
 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=
@@ -657,9 +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-20190813141303-74dc4d7220e7/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-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=
@@ -667,31 +718,51 @@ 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-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-20210614182718-04defd469f4e h1:XpT3nA5TvE525Ne3hInMh6+GETgn27Zfm9dxsThnX2Q=
+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=
@@ -704,47 +775,72 @@ golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5h
 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-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-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-20210423082822-04245dca01da h1:b3NXsE2LusjYGGjL5bxEVZZORm/YEFFrWFjR8eFrw/c=
+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 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
 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=
@@ -753,19 +849,17 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
 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/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE=
 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=
@@ -776,10 +870,10 @@ 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=
@@ -800,8 +894,30 @@ golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapK
 golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
 golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
 golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
 golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
+golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
+golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
+golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
+golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
 golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
+golang.org/x/tools v0.1.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=
@@ -817,14 +933,32 @@ 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=
@@ -843,13 +977,45 @@ 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-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-20210303154014-9728d6b83eeb h1:hcskBH5qZCOa7WpTUFUFvoebnSFZBYpjykLtjIp9DVk=
+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=
@@ -863,14 +1029,24 @@ google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQ
 google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
 google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
 google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
+google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
 google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
+google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
 google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
+google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
 google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
+google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
 google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
+google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
 google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
+google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
 google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
-google.golang.org/grpc v1.39.0 h1:Klz8I9kdtkIN6EpHHUOMLCYhTn/2WAe5a0s1hcBkdTI=
+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=
@@ -884,8 +1060,9 @@ 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=
@@ -896,17 +1073,15 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntN
 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/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
-gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
-gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
 gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
-gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
 gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+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=
@@ -930,25 +1105,9 @@ honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWh
 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 2dc1161bb4c48981c01613258ba25c2e9dd0ecd6..0000000000000000000000000000000000000000
--- a/nucleus/controller.go
+++ /dev/null
@@ -1,106 +0,0 @@
-package nucleus
-
-import (
-	"context"
-	"net/http"
-	"os"
-	"os/signal"
-	"sync"
-	"time"
-
-	"code.fbi.h-da.de/danet/gosdn/database"
-	"github.com/google/uuid"
-	log "github.com/sirupsen/logrus"
-)
-
-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 c55d83949f7a2e2868a0992b48f8986cefcf7ce3..7b6a5e84388b8474ca2a3ad119d48679c1c72306 100644
--- a/nucleus/device_test.go
+++ b/nucleus/device_test.go
@@ -4,7 +4,11 @@ import (
 	"reflect"
 	"testing"
 
-	"code.fbi.h-da.de/danet/forks/goarista/gnmi"
+	"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"
@@ -13,9 +17,10 @@ import (
 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
@@ -32,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)
@@ -48,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 65892db3e8e925eaccd33575fcbf8dc3b7e89690..37f6f772680f4de808f51b75c663fc14040e99b0 100644
--- a/nucleus/gnmi_transport.go
+++ b/nucleus/gnmi_transport.go
@@ -2,27 +2,24 @@ package nucleus
 
 import (
 	"context"
-	"reflect"
-	"strings"
+	"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"
-)
 
-// 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
@@ -30,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)
 }
@@ -130,46 +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{}}
-				return g.Unmarshal(val.JsonIetfVal, extraxtPathElements(fullPath), root, opts...)
-			}
-			// 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
+				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
-}
-
-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
@@ -179,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
@@ -193,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")
 
@@ -207,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() {
@@ -261,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 f8e655f740cd9f8453ab3e0d1fcc310d37546435..376f0363209eb0b9856b67511cefc0bf7e5ad18a 100644
--- a/nucleus/gnmi_transport_test.go
+++ b/nucleus/gnmi_transport_test.go
@@ -6,11 +6,17 @@ import (
 	"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"
@@ -99,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
@@ -191,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 {
@@ -210,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
@@ -229,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",
@@ -253,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]
@@ -270,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)
 			}
 		})
 	}
@@ -309,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
@@ -337,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
@@ -437,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
@@ -446,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,
 		},
@@ -492,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
@@ -509,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 fcea127ae75fdc15111c58e6b6471057c6880cc5..0000000000000000000000000000000000000000
--- a/nucleus/http.go
+++ /dev/null
@@ -1,208 +0,0 @@
-package nucleus
-
-import (
-	"context"
-	"fmt"
-	"net/http"
-	"net/url"
-	"time"
-
-	"code.fbi.h-da.de/danet/forks/goarista/gnmi"
-	"github.com/google/uuid"
-	gpb "github.com/openconfig/gnmi/proto/gnmi"
-	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("/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 24022b423a507bd25c9ca58c9d18b7da7dd2e7fa..0000000000000000000000000000000000000000
--- a/nucleus/http_test.go
+++ /dev/null
@@ -1,172 +0,0 @@
-package nucleus
-
-import (
-	"errors"
-	"net/http"
-	"testing"
-
-	"code.fbi.h-da.de/danet/gosdn/mocks"
-	"github.com/google/uuid"
-	log "github.com/sirupsen/logrus"
-	"github.com/stretchr/testify/mock"
-)
-
-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 04e73ea9fafaa537c005ef555fa19110a522862a..f0d9b10981d71eb2b8b6c0617aa6809b7c064c17 100644
--- a/nucleus/initialise_test.go
+++ b/nucleus/initialise_test.go
@@ -5,6 +5,11 @@ import (
 	"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"
@@ -16,8 +21,6 @@ import (
 	pb "google.golang.org/protobuf/proto"
 )
 
-const apiEndpoint = "http://localhost:8080"
-
 // UUIDs for test cases
 var did uuid.UUID
 var mdid uuid.UUID
@@ -26,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 })
 
@@ -69,9 +68,7 @@ func TestMain(m *testing.M) {
 		}
 	}
 	readTestUUIDs()
-
 	testSetupGnmi()
-	testSetupHTTP()
 	os.Exit(m.Run())
 }
 
@@ -90,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),
 	}
 }
 
@@ -112,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 07e5fbc29af94e24938474cf50e5654409484fec..2c7d845514419c74322e3381b71e4855a72f4ac6 100644
--- a/nucleus/principalNetworkDomain.go
+++ b/nucleus/principalNetworkDomain.go
@@ -2,78 +2,134 @@ package nucleus
 
 import (
 	"context"
+	"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"
-	log "github.com/sirupsen/logrus"
+	"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"
 
-	"encoding/json"
+	"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
@@ -82,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)
@@ -124,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 76f35915df0faf787a465206efbbe3db3bf11892..2aabcd29814271b38539dfbef5def11827ff348e 100644
--- a/nucleus/principalNetworkDomain_test.go
+++ b/nucleus/principalNetworkDomain_test.go
@@ -2,30 +2,48 @@ package nucleus
 
 import (
 	"errors"
+	"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
 	}{
 		{
@@ -36,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
@@ -73,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
@@ -82,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 d.Name() != tt.args.name {
+						t.Errorf("AddDevice() got = %v, want %v", d.Name(), tt.args.name)
 					}
-					if err := pnd.devices.delete(did); err != nil {
+					if err := pnd.devices.Delete(d.ID()); err != nil {
 						t.Error(err)
 					}
 				}
@@ -131,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
@@ -158,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 {
@@ -180,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)
 					}
 				}
@@ -195,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
@@ -206,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)
 			}
 		})
@@ -239,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
@@ -252,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,
 			}
@@ -302,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) {
@@ -316,6 +324,8 @@ func Test_pndImplementation_GetSBIs(t *testing.T) {
 }
 
 func Test_pndImplementation_MarshalDevice(t *testing.T) {
+	removeExistingPNDStore()
+
 	type args struct {
 		uuid uuid.UUID
 	}
@@ -332,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
@@ -352,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)
 			}
 		})
@@ -360,6 +371,8 @@ func Test_pndImplementation_MarshalDevice(t *testing.T) {
 }
 
 func Test_pndImplementation_RemoveDevice(t *testing.T) {
+	removeExistingPNDStore()
+
 	type args struct {
 		uuid uuid.UUID
 	}
@@ -372,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)
 				}
@@ -384,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)
 			}
 		})
@@ -392,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
 	}
@@ -403,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
@@ -458,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)
 			}
 		})
@@ -477,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
@@ -506,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 ae6584a88b680952a4882aa3bd374bc93bcbf92e..06ae108a4332f8e349153cbe79d03b65f55c40f0 100644
--- a/nucleus/restconf_transport.go
+++ b/nucleus/restconf_transport.go
@@ -3,35 +3,41 @@ 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 4f174f5fbfb19f00be9ef0af0d4df72921b32f98..e722632a7e062d3aaacec802611df7861e0fde43 100644
--- a/nucleus/restconf_transport_test.go
+++ b/nucleus/restconf_transport_test.go
@@ -62,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 aa5f67c42313c1b131629151bebe019720a66e61..d62411738bac97389cbf9173755c35e53a686b80 100644
--- a/nucleus/southbound.go
+++ b/nucleus/southbound.go
@@ -1,34 +1,42 @@
 package nucleus
 
 import (
-	"reflect"
+	"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"
 )
 
-// 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.
@@ -56,96 +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 {
-		return ytypes.SetNode(schema, root.(*openconfig.Device), path, val, opts...)
-	}
+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 d11d21d218e46317da60ddd6577ba9976ca2f91f..b13f3bb30e1cf672a95f01ceac177978c12d01b1 100644
--- a/nucleus/southbound_test.go
+++ b/nucleus/southbound_test.go
@@ -4,18 +4,20 @@ import (
 	"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"
 )
 
 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
@@ -102,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 {
@@ -111,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",
@@ -119,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,
 			},
@@ -162,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")
@@ -173,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 ff8d21319cbef85d4d0b9c8c5c5a02567c425631..0000000000000000000000000000000000000000
--- a/nucleus/store.go
+++ /dev/null
@@ -1,142 +0,0 @@
-package nucleus
-
-import (
-	"reflect"
-	"sync"
-
-	"github.com/google/uuid"
-	log "github.com/sirupsen/logrus"
-)
-
-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 08affc9c5ef4839e4ecbbacaf7f0b00f1f712c84..0000000000000000000000000000000000000000
--- a/nucleus/store_test.go
+++ /dev/null
@@ -1,438 +0,0 @@
-package nucleus
-
-import (
-	"reflect"
-	"sort"
-	"testing"
-
-	"code.fbi.h-da.de/danet/gosdn/mocks"
-	"github.com/google/uuid"
-)
-
-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 21f5ca56e30ba41d03349ed76651147b5f8a4ce5..49d74e1c2d3795a9b2a987625b756be7b4939ef6 100644
--- a/nucleus/transport.go
+++ b/nucleus/transport.go
@@ -1,42 +1,38 @@
 package nucleus
 
 import (
-	"bytes"
-	"context"
-	"io"
-
-	"github.com/openconfig/ygot/ytypes"
+	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
-}
-
-// 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
+// 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}
+	}
 }
 
-// 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 c246ebddff0d5fe9396faa22ff9cb6ca5b923e09..403ffc5e441f86013e3eb35a7b6ab331e50b0fb9 100644
--- a/nucleus/util/path/path_traversal.go
+++ b/nucleus/util/path/traverse.go
@@ -71,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)
@@ -81,7 +80,8 @@ func Strings(paths map[string]*Element) []string {
 		stringBuilder(ch, &b, v)
 	}
 	stop <- true
-	p = <-val
+	p := <-val
+
 	return p
 }
 
@@ -95,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 100%
rename from nucleus/util/path/path_traversal_test.go
rename to nucleus/util/path/traverse_test.go
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/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.yml b/test/containerlab/int01.clab.tmpl.yml
similarity index 100%
rename from test/containerlab/int01.clab.yml
rename to test/containerlab/int01.clab.tmpl.yml
diff --git a/test/integration/cliIntegration_test.go b/test/integration/cliIntegration_test.go
deleted file mode 100644
index 50decc0629d948b4d4f0591e6eb8fd603149d34b..0000000000000000000000000000000000000000
--- a/test/integration/cliIntegration_test.go
+++ /dev/null
@@ -1,194 +0,0 @@
-package integration
-
-import (
-	"code.fbi.h-da.de/danet/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 68cdc3cead26237756b22f62f4b9baff03096b14..0000000000000000000000000000000000000000
--- a/test/integration/cmdIntegration_test.go
+++ /dev/null
@@ -1,180 +0,0 @@
-package integration
-
-import (
-	"os"
-	"testing"
-
-	"code.fbi.h-da.de/danet/forks/goarista/gnmi"
-	"code.fbi.h-da.de/danet/gosdn/cli"
-	"code.fbi.h-da.de/danet/gosdn/nucleus"
-	"code.fbi.h-da.de/danet/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"
-)
-
-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 e1e8cfbf0b42d26f2059a05ccf5f029aadb67b31..68ac907101bd4fb1dd82c2289821e820c9411030 100644
--- a/test/integration/nucleusIntegration_test.go
+++ b/test/integration/nucleusIntegration_test.go
@@ -2,96 +2,242 @@ package integration
 
 import (
 	"context"
+	"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)
+				}
 			}
 		})
 	}
@@ -107,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
@@ -132,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,
@@ -148,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
@@ -170,7 +317,7 @@ func TestGnmi_SubscribeIntegration(t *testing.T) {
 	}
 
 	type fields struct {
-		opt *nucleus.GnmiTransportOptions
+		opt *tpb.TransportOption
 	}
 	type args struct {
 		ctx  context.Context
@@ -185,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{
@@ -209,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{
@@ -232,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{
@@ -248,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)
 						}
 					}
 				}
@@ -277,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
@@ -312,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()},
@@ -325,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/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