diff --git a/.circleci/config.yml b/.circleci/config.yml
index 4c0ec6f309e0..ca937349a2ef 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -893,13 +893,15 @@ jobs:
SWAGGER_CODEGEN_JAR: /home/circleci/project/.codegen/swagger-codegen-cli.jar
steps:
- checkout
+ - python/set_version
- build/determinator:
<<: *lte_build_verify
- run: mkdir -p /var/tmp/test_results
- run: mkdir -p /var/tmp/codecovs
- run: sudo apt-get update -y
- run: sudo apt-get install -y libsystemd-dev pkg-config curl zip unzip
- - run: sudo apt-get install -y virtualenv python-babel python-dev build-essential python3-setuptools python-setuptools autogen autoconf libtool python3-apt python3-aioeventlet python3-requests python3-pip python-protobuf
+ - run: sudo apt-get install -y virtualenv python-babel python-dev build-essential autogen autoconf libtool python3-apt python3-aioeventlet python3-requests python3-pip python-protobuf
+ - run: pip3 install setuptools==49.6.0
- run:
command: |
sudo curl -Lfs https://github.com/google/protobuf/releases/download/v3.1.0/protoc-3.1.0-linux-x86_64.zip -o protoc3.zip
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 30541d7cf431..bd14ee367829 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -23,3 +23,14 @@
All upgrade instructions for backwards-breaking changes will be aggregated
in the next release's changelog so this is very important to fill out.
-->
+
+
diff --git a/.github/workflows/hadolint.yml b/.github/workflows/hadolint.yml
new file mode 100644
index 000000000000..0296e6d89fba
--- /dev/null
+++ b/.github/workflows/hadolint.yml
@@ -0,0 +1,18 @@
+---
+name: Dockerfile Linting
+on: [pull_request] # yamllint disable-line rule:truthy
+jobs:
+ hadolint:
+ name: Dockerfile Lint
+ runs-on: ubuntu-latest
+ steps:
+ - name: Check out code
+ uses: actions/checkout@v1
+ - name: hadolint
+ uses: reviewdog/action-hadolint@v1
+ with:
+ github_token: ${{ secrets.github_token }}
+ reporter: github-pr-review # Default is github-pr-check
+ # Ignore DL3005-"Do not use apt-get upgrade or dist-upgrade"
+ hadolint_ignore: DL3005
+ filter_mode: added # All added or modified lines
diff --git a/.github/workflows/misspell.yml b/.github/workflows/misspell.yml
new file mode 100644
index 000000000000..b572f2cbef4c
--- /dev/null
+++ b/.github/workflows/misspell.yml
@@ -0,0 +1,17 @@
+---
+name: reviewdog
+on: [pull_request] # yamllint disable-line rule:truthy
+jobs:
+ misspell:
+ name: runner / misspell
+ runs-on: ubuntu-latest
+ steps:
+ - name: Check out code.
+ uses: actions/checkout@v1
+ - name: misspell
+ uses: reviewdog/action-misspell@v1
+ with:
+ github_token: ${{ secrets.github_token }}
+ filter_mode: added # Any added or changed content.
+ reporter: github-pr-review # Post code review comments.
+ locale: "US"
diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml
index 0e8522c3b713..5a87a73e4de4 100644
--- a/.github/workflows/shellcheck.yml
+++ b/.github/workflows/shellcheck.yml
@@ -1,4 +1,4 @@
-name: Shellcheck by Reviewdog
+name: reviewdog
on: [pull_request]
jobs:
shellcheck:
@@ -10,8 +10,8 @@ jobs:
uses: reviewdog/action-shellcheck@v1
with:
github_token: ${{ secrets.github_token }}
- filter_mode: diff_context # Any changed content.
- reporter: github-pr-review # Post code review comments.
+ filter_mode: added # Any added or changed content.
+ reporter: github-pr-review # Post code review comments. Falls back to Annotations.
pattern: "*.sh" # Optional.
# Other options omitted here but possible.
# - fail_on_error
diff --git a/.github/workflows/wemake-python-styleguide.yml b/.github/workflows/wemake-python-styleguide.yml
new file mode 100644
index 000000000000..ce96eec35bbf
--- /dev/null
+++ b/.github/workflows/wemake-python-styleguide.yml
@@ -0,0 +1,23 @@
+name: Python linting by Reviewdog
+on: [pull_request]
+jobs:
+ wemake-python-styleguide:
+ name: runner / wemake-python-styleguide
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ with:
+ fetch-depth: 0
+ - name: Get changed files
+ id: py-changes
+ # Set outputs.py to be a list of modified python files
+ run: |
+ echo "::set-output name=py::$(git diff --name-only --diff-filter=ACMRT ${{ github.event.pull_request.base.sha }} ${{ github.sha }} | grep .py$ | xargs)"
+ - if: ${{ steps.py-changes.outputs.py }}
+ name: wemake-python-styleguide
+ uses: wemake-services/wemake-python-styleguide@0.15.2
+ with:
+ reporter: 'github-pr-review'
+ path: ${{ steps.py-changes.outputs.py }}
+ env:
+ GITHUB_TOKEN: ${{ secrets.github_token }}
diff --git a/.github/workflows/yamlint.yml b/.github/workflows/yamlint.yml
new file mode 100644
index 000000000000..ca9521ed5684
--- /dev/null
+++ b/.github/workflows/yamlint.yml
@@ -0,0 +1,16 @@
+---
+name: reviewdog
+on: [pull_request] # yamllint disable-line rule:truthy
+jobs:
+ yamllint:
+ name: runner / yamllint
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v1
+ - name: yamllint
+ uses: reviewdog/action-yamllint@v1
+ with:
+ github_token: ${{ secrets.github_token }}
+ level: warning
+ filter_mode: added # Any added or changed content.
+ reporter: github-pr-review # Comments on PR with review comments.
diff --git a/.gitignore b/.gitignore
index 1e3e6667fb3e..5204d9a340a0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -94,6 +94,7 @@ test_results_magma_converged_mme.html
# VS Code
.vscode/
+.venv/
# Internal
fb
@@ -105,3 +106,5001 @@ fb
orc8r/cloud/coverage/
feg/gateway/coverage/
lte/gateway/c/oai/code_coverage/
+pkg/mod/*
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/.gitignore
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/.travis.yml
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/case_test.go
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/case.go
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/delete_ctx_test.go
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/delete_ctx.go
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/delete_test.go
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/delete.go
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/expr_test.go
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/expr.go
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/go.mod
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/go.sum
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/insert_ctx_test.go
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/insert_ctx.go
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/insert_test.go
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/insert.go
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/integration_test.go
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/LICENSE.txt
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/part.go
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/placeholder_test.go
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/placeholder.go
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/README.md
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/row_test.go
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/row.go
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/select_ctx_test.go
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/select_ctx.go
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/select_test.go
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/select.go
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/squirrel_ctx_test.go
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/squirrel_ctx.go
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/squirrel_test.go
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/squirrel.go
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/statement_test.go
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/statement.go
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/stmtcacher_ctx_test.go
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/stmtcacher_ctx.go
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/stmtcacher_noctx.go
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/stmtcacher_test.go
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/stmtcacher.go
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/update_ctx_test.go
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/update_ctx.go
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/update_test.go
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/update.go
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/where_test.go
+pkg/mod/github.com/!masterminds/squirrel@v1.1.1-0.20190513200039-d13326f0be73/where.go
+pkg/mod/github.com/!puerkito!bio/purell@v1.1.1/.gitignore
+pkg/mod/github.com/!puerkito!bio/purell@v1.1.1/.travis.yml
+pkg/mod/github.com/!puerkito!bio/purell@v1.1.1/bench_test.go
+pkg/mod/github.com/!puerkito!bio/purell@v1.1.1/example_test.go
+pkg/mod/github.com/!puerkito!bio/purell@v1.1.1/LICENSE
+pkg/mod/github.com/!puerkito!bio/purell@v1.1.1/purell_test.go
+pkg/mod/github.com/!puerkito!bio/purell@v1.1.1/purell.go
+pkg/mod/github.com/!puerkito!bio/purell@v1.1.1/README.md
+pkg/mod/github.com/!puerkito!bio/purell@v1.1.1/urlnorm_test.go
+pkg/mod/github.com/!puerkito!bio/purell@v1.1.1/benchmarks/v0.1.0
+pkg/mod/github.com/!puerkito!bio/urlesc@v0.0.0-20170810143723-de5bf2ad4578/.travis.yml
+pkg/mod/github.com/!puerkito!bio/urlesc@v0.0.0-20170810143723-de5bf2ad4578/LICENSE
+pkg/mod/github.com/!puerkito!bio/urlesc@v0.0.0-20170810143723-de5bf2ad4578/README.md
+pkg/mod/github.com/!puerkito!bio/urlesc@v0.0.0-20170810143723-de5bf2ad4578/urlesc_test.go
+pkg/mod/github.com/!puerkito!bio/urlesc@v0.0.0-20170810143723-de5bf2ad4578/urlesc.go
+pkg/mod/github.com/asaskevich/govalidator@v0.0.0-20190424111038-f61b66f89f4a/.travis.yml
+pkg/mod/github.com/asaskevich/govalidator@v0.0.0-20190424111038-f61b66f89f4a/arrays_test.go
+pkg/mod/github.com/asaskevich/govalidator@v0.0.0-20190424111038-f61b66f89f4a/arrays.go
+pkg/mod/github.com/asaskevich/govalidator@v0.0.0-20190424111038-f61b66f89f4a/CONTRIBUTING.md
+pkg/mod/github.com/asaskevich/govalidator@v0.0.0-20190424111038-f61b66f89f4a/converter_test.go
+pkg/mod/github.com/asaskevich/govalidator@v0.0.0-20190424111038-f61b66f89f4a/converter.go
+pkg/mod/github.com/asaskevich/govalidator@v0.0.0-20190424111038-f61b66f89f4a/error_test.go
+pkg/mod/github.com/asaskevich/govalidator@v0.0.0-20190424111038-f61b66f89f4a/error.go
+pkg/mod/github.com/asaskevich/govalidator@v0.0.0-20190424111038-f61b66f89f4a/LICENSE
+pkg/mod/github.com/asaskevich/govalidator@v0.0.0-20190424111038-f61b66f89f4a/numerics_test.go
+pkg/mod/github.com/asaskevich/govalidator@v0.0.0-20190424111038-f61b66f89f4a/numerics.go
+pkg/mod/github.com/asaskevich/govalidator@v0.0.0-20190424111038-f61b66f89f4a/patterns.go
+pkg/mod/github.com/asaskevich/govalidator@v0.0.0-20190424111038-f61b66f89f4a/README.md
+pkg/mod/github.com/asaskevich/govalidator@v0.0.0-20190424111038-f61b66f89f4a/types.go
+pkg/mod/github.com/asaskevich/govalidator@v0.0.0-20190424111038-f61b66f89f4a/utils_benchmark_test.go
+pkg/mod/github.com/asaskevich/govalidator@v0.0.0-20190424111038-f61b66f89f4a/utils_test.go
+pkg/mod/github.com/asaskevich/govalidator@v0.0.0-20190424111038-f61b66f89f4a/utils.go
+pkg/mod/github.com/asaskevich/govalidator@v0.0.0-20190424111038-f61b66f89f4a/validator_test.go
+pkg/mod/github.com/asaskevich/govalidator@v0.0.0-20190424111038-f61b66f89f4a/validator.go
+pkg/mod/github.com/asaskevich/govalidator@v0.0.0-20190424111038-f61b66f89f4a/wercker.yml
+pkg/mod/github.com/asaskevich/govalidator@v0.0.0-20190424111038-f61b66f89f4a/.circleci/config.yml
+pkg/mod/github.com/asaskevich/govalidator@v0.0.0-20190424111038-f61b66f89f4a/.github/ISSUE_TEMPLATE.md
+pkg/mod/github.com/beorn7/perks@v1.0.1/.gitignore
+pkg/mod/github.com/beorn7/perks@v1.0.1/go.mod
+pkg/mod/github.com/beorn7/perks@v1.0.1/LICENSE
+pkg/mod/github.com/beorn7/perks@v1.0.1/README.md
+pkg/mod/github.com/beorn7/perks@v1.0.1/VERSION
+pkg/mod/github.com/beorn7/perks@v1.0.1/histogram/bench_test.go
+pkg/mod/github.com/beorn7/perks@v1.0.1/histogram/histogram_test.go
+pkg/mod/github.com/beorn7/perks@v1.0.1/histogram/histogram.go
+pkg/mod/github.com/beorn7/perks@v1.0.1/quantile/bench_test.go
+pkg/mod/github.com/beorn7/perks@v1.0.1/quantile/example_test.go
+pkg/mod/github.com/beorn7/perks@v1.0.1/quantile/exampledata.txt
+pkg/mod/github.com/beorn7/perks@v1.0.1/quantile/stream_test.go
+pkg/mod/github.com/beorn7/perks@v1.0.1/quantile/stream.go
+pkg/mod/github.com/beorn7/perks@v1.0.1/topk/topk_test.go
+pkg/mod/github.com/beorn7/perks@v1.0.1/topk/topk.go
+pkg/mod/github.com/cespare/xxhash/v2@v2.1.1/.travis.yml
+pkg/mod/github.com/cespare/xxhash/v2@v2.1.1/go.mod
+pkg/mod/github.com/cespare/xxhash/v2@v2.1.1/go.sum
+pkg/mod/github.com/cespare/xxhash/v2@v2.1.1/LICENSE.txt
+pkg/mod/github.com/cespare/xxhash/v2@v2.1.1/README.md
+pkg/mod/github.com/cespare/xxhash/v2@v2.1.1/xxhash_amd64.go
+pkg/mod/github.com/cespare/xxhash/v2@v2.1.1/xxhash_amd64.s
+pkg/mod/github.com/cespare/xxhash/v2@v2.1.1/xxhash_other.go
+pkg/mod/github.com/cespare/xxhash/v2@v2.1.1/xxhash_safe.go
+pkg/mod/github.com/cespare/xxhash/v2@v2.1.1/xxhash_test.go
+pkg/mod/github.com/cespare/xxhash/v2@v2.1.1/xxhash_unsafe_test.go
+pkg/mod/github.com/cespare/xxhash/v2@v2.1.1/xxhash_unsafe.go
+pkg/mod/github.com/cespare/xxhash/v2@v2.1.1/xxhash.go
+pkg/mod/github.com/cespare/xxhash/v2@v2.1.1/xxhsum/.gitignore
+pkg/mod/github.com/cespare/xxhash/v2@v2.1.1/xxhsum/xxhsum.go
+pkg/mod/github.com/cespare/xxhash@v1.1.0/go.mod
+pkg/mod/github.com/cespare/xxhash@v1.1.0/go.sum
+pkg/mod/github.com/cespare/xxhash@v1.1.0/LICENSE.txt
+pkg/mod/github.com/cespare/xxhash@v1.1.0/README.md
+pkg/mod/github.com/cespare/xxhash@v1.1.0/rotate.go
+pkg/mod/github.com/cespare/xxhash@v1.1.0/rotate19.go
+pkg/mod/github.com/cespare/xxhash@v1.1.0/xxhash_amd64_test.go
+pkg/mod/github.com/cespare/xxhash@v1.1.0/xxhash_amd64.go
+pkg/mod/github.com/cespare/xxhash@v1.1.0/xxhash_amd64.s
+pkg/mod/github.com/cespare/xxhash@v1.1.0/xxhash_other.go
+pkg/mod/github.com/cespare/xxhash@v1.1.0/xxhash_safe.go
+pkg/mod/github.com/cespare/xxhash@v1.1.0/xxhash_test.go
+pkg/mod/github.com/cespare/xxhash@v1.1.0/xxhash_unsafe.go
+pkg/mod/github.com/cespare/xxhash@v1.1.0/xxhash.go
+pkg/mod/github.com/cespare/xxhash@v1.1.0/xxhsum/.gitignore
+pkg/mod/github.com/cespare/xxhash@v1.1.0/xxhsum/xxhsum.go
+pkg/mod/github.com/davecgh/go-spew@v1.1.1/.gitignore
+pkg/mod/github.com/davecgh/go-spew@v1.1.1/.travis.yml
+pkg/mod/github.com/davecgh/go-spew@v1.1.1/cov_report.sh
+pkg/mod/github.com/davecgh/go-spew@v1.1.1/LICENSE
+pkg/mod/github.com/davecgh/go-spew@v1.1.1/README.md
+pkg/mod/github.com/davecgh/go-spew@v1.1.1/test_coverage.txt
+pkg/mod/github.com/davecgh/go-spew@v1.1.1/spew/bypass.go
+pkg/mod/github.com/davecgh/go-spew@v1.1.1/spew/bypasssafe.go
+pkg/mod/github.com/davecgh/go-spew@v1.1.1/spew/common_test.go
+pkg/mod/github.com/davecgh/go-spew@v1.1.1/spew/common.go
+pkg/mod/github.com/davecgh/go-spew@v1.1.1/spew/config.go
+pkg/mod/github.com/davecgh/go-spew@v1.1.1/spew/doc.go
+pkg/mod/github.com/davecgh/go-spew@v1.1.1/spew/dump_test.go
+pkg/mod/github.com/davecgh/go-spew@v1.1.1/spew/dump.go
+pkg/mod/github.com/davecgh/go-spew@v1.1.1/spew/dumpcgo_test.go
+pkg/mod/github.com/davecgh/go-spew@v1.1.1/spew/dumpnocgo_test.go
+pkg/mod/github.com/davecgh/go-spew@v1.1.1/spew/example_test.go
+pkg/mod/github.com/davecgh/go-spew@v1.1.1/spew/format_test.go
+pkg/mod/github.com/davecgh/go-spew@v1.1.1/spew/format.go
+pkg/mod/github.com/davecgh/go-spew@v1.1.1/spew/internal_test.go
+pkg/mod/github.com/davecgh/go-spew@v1.1.1/spew/internalunsafe_test.go
+pkg/mod/github.com/davecgh/go-spew@v1.1.1/spew/spew_test.go
+pkg/mod/github.com/davecgh/go-spew@v1.1.1/spew/spew.go
+pkg/mod/github.com/davecgh/go-spew@v1.1.1/spew/testdata/dumpcgo.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/.golangci.yml
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/CODE_OF_CONDUCT.md
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/CONTRIBUTING.md
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/ent.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/go.mod
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/go.sum
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/LICENSE
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/README.md
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/.circleci/config.yml
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/cmd/entc/entc.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/cmd/entc/packages_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/cmd/entc/packages.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/cmd/entc/print_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/cmd/entc/print.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/dialect.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/client_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/client.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/config_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/config.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/driver.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/example_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/expand_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/expand.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/http_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/http.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/request_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/request.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/response_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/response.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/status_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/status.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/tokens.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/encoding/mime_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/encoding/mime.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/encoding/graphson/bench_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/encoding/graphson/common_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/encoding/graphson/decode_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/encoding/graphson/decode.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/encoding/graphson/encode_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/encoding/graphson/encode.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/encoding/graphson/error_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/encoding/graphson/error.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/encoding/graphson/extension.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/encoding/graphson/init.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/encoding/graphson/interface_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/encoding/graphson/interface.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/encoding/graphson/lazy_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/encoding/graphson/lazy.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/encoding/graphson/map_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/encoding/graphson/map.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/encoding/graphson/marshaler_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/encoding/graphson/marshaler.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/encoding/graphson/native_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/encoding/graphson/native.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/encoding/graphson/raw_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/encoding/graphson/raw.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/encoding/graphson/slice_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/encoding/graphson/slice.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/encoding/graphson/struct_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/encoding/graphson/struct.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/encoding/graphson/tags_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/encoding/graphson/tags.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/encoding/graphson/time_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/encoding/graphson/time.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/encoding/graphson/type_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/encoding/graphson/type.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/encoding/graphson/util_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/encoding/graphson/util.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/graph/edge_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/graph/edge.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/graph/element.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/graph/valuemap_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/graph/valuemap.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/graph/vertex_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/graph/vertex.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/graph/dsl/dsl_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/graph/dsl/dsl.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/graph/dsl/traversal.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/graph/dsl/__/dsl.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/graph/dsl/g/g.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/graph/dsl/p/p.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/internal/ws/conn_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/internal/ws/conn.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/ocgremlin/client_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/ocgremlin/client.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/ocgremlin/stats_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/ocgremlin/stats.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/ocgremlin/trace_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/gremlin/ocgremlin/trace.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/sql/builder_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/sql/builder.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/sql/driver.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/sql/graph_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/sql/graph.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/sql/scan_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/sql/scan.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/sql/sql_112.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/sql/sql_113.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/sql/schema/migrate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/sql/schema/mysql_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/sql/schema/mysql.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/sql/schema/postgres_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/sql/schema/postgres.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/sql/schema/schema_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/sql/schema/schema.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/sql/schema/sqlite_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/sql/schema/sqlite.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/sql/schema/writer_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/dialect/sql/schema/writer.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/doc/.gitignore
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/doc/md/aggregate.md
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/doc/md/code-gen.md
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/doc/md/crud.md
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/doc/md/dialects.md
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/doc/md/getting-started.md
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/doc/md/migrate.md
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/doc/md/paging.md
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/doc/md/predicates.md
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/doc/md/schema-config.md
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/doc/md/schema-def.md
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/doc/md/schema-edges.md
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/doc/md/schema-fields.md
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/doc/md/schema-indexes.md
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/doc/md/schema-mixin.md
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/doc/md/sql-integration.md
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/doc/md/transactions.md
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/doc/md/traversals.md
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/doc/website/package.json
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/doc/website/README.md
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/doc/website/sidebars.json
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/doc/website/siteConfig.js
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/doc/website/blog/2019-10-03-introducing-ent.md
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/doc/website/core/Footer.js
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/doc/website/pages/en/index.js
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/doc/website/static/css/code-block-buttons.css
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/doc/website/static/css/custom.css
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/doc/website/static/font/CalibreBold.woff
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/doc/website/static/font/CalibreLight.woff
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/doc/website/static/font/CalibreLightItalic.woff
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/doc/website/static/font/CalibreMedium.woff
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/doc/website/static/font/CalibreMediumItalic.woff
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/doc/website/static/font/CalibreRegular.woff
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/doc/website/static/font/CalibreRegularItalic.woff
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/doc/website/static/font/CalibreSemibold.woff
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/doc/website/static/font/CalibreThin.woff
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/doc/website/static/font/CalibreThinItalic.woff
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/doc/website/static/img/favicon.ico
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/doc/website/static/img/logo.png
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/doc/website/static/img/oss_logo.png
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/doc/website/static/js/code-block-buttons.js
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/doc/website/static/js/custom.js
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/entc.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/tools.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/func.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/graph_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/graph.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/predicate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/storage.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/type_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/type.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/internal/bindata.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/base.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/client.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/config.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/context.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/ent.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/example.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/header.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/import.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/meta.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/predicate.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/tx.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/where.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/builder/create.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/builder/delete.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/builder/query.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/builder/setter.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/builder/update.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/dialect/gremlin/by.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/dialect/gremlin/create.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/dialect/gremlin/decode.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/dialect/gremlin/delete.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/dialect/gremlin/errors.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/dialect/gremlin/globals.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/dialect/gremlin/group.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/dialect/gremlin/meta.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/dialect/gremlin/open.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/dialect/gremlin/predicate.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/dialect/gremlin/query.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/dialect/gremlin/select.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/dialect/gremlin/update.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/dialect/sql/by.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/dialect/sql/create.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/dialect/sql/decode.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/dialect/sql/delete.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/dialect/sql/errors.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/dialect/sql/globals.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/dialect/sql/group.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/dialect/sql/meta.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/dialect/sql/open.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/dialect/sql/predicate.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/dialect/sql/query.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/dialect/sql/select.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/dialect/sql/update.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/migrate/migrate.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/gen/template/migrate/schema.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/generate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/index_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/integration_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/README.md
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/relation_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/type_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/compose/docker-compose.yaml
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/compose/Dockerfile
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/compose/gremlin-server/Dockerfile
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/compose/gremlin-server/gremlin-server.yaml
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/compose/gremlin-server/tinkergraph-empty.properties
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/config/config_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/config/ent/client.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/config/ent/config.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/config/ent/context.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/config/ent/ent.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/config/ent/example_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/config/ent/tx.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/config/ent/user_create.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/config/ent/user_delete.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/config/ent/user_query.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/config/ent/user_update.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/config/ent/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/config/ent/migrate/migrate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/config/ent/migrate/schema.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/config/ent/predicate/predicate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/config/ent/schema/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/config/ent/user/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/config/ent/user/where.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/customid/customid_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/customid/ent/blob_create.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/customid/ent/blob_delete.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/customid/ent/blob_query.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/customid/ent/blob_update.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/customid/ent/blob.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/customid/ent/client.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/customid/ent/config.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/customid/ent/context.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/customid/ent/ent.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/customid/ent/example_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/customid/ent/group_create.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/customid/ent/group_delete.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/customid/ent/group_query.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/customid/ent/group_update.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/customid/ent/group.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/customid/ent/tx.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/customid/ent/user_create.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/customid/ent/user_delete.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/customid/ent/user_query.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/customid/ent/user_update.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/customid/ent/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/customid/ent/blob/blob.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/customid/ent/blob/where.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/customid/ent/group/group.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/customid/ent/group/where.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/customid/ent/migrate/migrate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/customid/ent/migrate/schema.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/customid/ent/predicate/predicate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/customid/ent/schema/blob.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/customid/ent/schema/group.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/customid/ent/schema/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/customid/ent/user/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/customid/ent/user/where.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/card_create.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/card_delete.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/card_query.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/card_update.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/card.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/client.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/comment_create.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/comment_delete.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/comment_query.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/comment_update.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/comment.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/config.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/context.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/ent.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/example_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/fieldtype_create.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/fieldtype_delete.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/fieldtype_query.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/fieldtype_update.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/fieldtype.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/file_create.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/file_delete.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/file_query.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/file_update.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/file.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/filetype_create.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/filetype_delete.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/filetype_query.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/filetype_update.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/filetype.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/group_create.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/group_delete.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/group_query.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/group_update.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/group.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/groupinfo_create.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/groupinfo_delete.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/groupinfo_query.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/groupinfo_update.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/groupinfo.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/item_create.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/item_delete.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/item_query.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/item_update.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/item.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/node_create.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/node_delete.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/node_query.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/node_update.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/node.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/pet_create.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/pet_delete.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/pet_query.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/pet_update.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/pet.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/tx.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/user_create.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/user_delete.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/user_query.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/user_update.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/card/card.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/card/where.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/comment/comment.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/comment/where.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/fieldtype/fieldtype.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/fieldtype/where.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/file/file.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/file/where.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/filetype/filetype.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/filetype/where.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/group/group.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/group/where.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/groupinfo/groupinfo.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/groupinfo/where.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/item/item.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/item/where.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/migrate/migrate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/migrate/schema.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/node/node.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/node/where.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/pet/pet.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/pet/where.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/predicate/predicate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/schema/card.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/schema/comment.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/schema/fieldtype.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/schema/file.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/schema/filetype.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/schema/group.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/schema/groupinfo.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/schema/item.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/schema/node.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/schema/pet.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/schema/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/template/fields.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/user/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/ent/user/where.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/idtype/idtype_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/idtype/ent/client.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/idtype/ent/config.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/idtype/ent/context.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/idtype/ent/ent.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/idtype/ent/example_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/idtype/ent/tx.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/idtype/ent/user_create.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/idtype/ent/user_delete.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/idtype/ent/user_query.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/idtype/ent/user_update.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/idtype/ent/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/idtype/ent/migrate/migrate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/idtype/ent/migrate/schema.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/idtype/ent/predicate/predicate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/idtype/ent/schema/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/idtype/ent/user/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/idtype/ent/user/where.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/json/json_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/json/ent/client.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/json/ent/config.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/json/ent/context.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/json/ent/ent.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/json/ent/example_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/json/ent/tx.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/json/ent/user_create.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/json/ent/user_delete.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/json/ent/user_query.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/json/ent/user_update.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/json/ent/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/json/ent/migrate/migrate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/json/ent/migrate/schema.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/json/ent/predicate/predicate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/json/ent/schema/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/json/ent/user/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/json/ent/user/where.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/migrate_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv1/client.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv1/config.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv1/context.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv1/ent.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv1/example_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv1/tx.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv1/user_create.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv1/user_delete.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv1/user_query.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv1/user_update.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv1/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv1/migrate/migrate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv1/migrate/schema.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv1/predicate/predicate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv1/schema/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv1/user/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv1/user/where.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv2/client.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv2/config.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv2/context.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv2/ent.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv2/example_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv2/group_create.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv2/group_delete.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv2/group_query.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv2/group_update.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv2/group.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv2/pet_create.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv2/pet_delete.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv2/pet_query.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv2/pet_update.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv2/pet.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv2/tx.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv2/user_create.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv2/user_delete.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv2/user_query.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv2/user_update.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv2/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv2/group/group.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv2/group/where.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv2/migrate/migrate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv2/migrate/schema.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv2/pet/pet.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv2/pet/where.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv2/predicate/predicate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv2/schema/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv2/user/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/migrate/entv2/user/where.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/template/template_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/template/ent/client.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/template/ent/config.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/template/ent/context.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/template/ent/ent.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/template/ent/example_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/template/ent/group_create.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/template/ent/group_delete.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/template/ent/group_query.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/template/ent/group_update.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/template/ent/group.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/template/ent/node.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/template/ent/pet_create.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/template/ent/pet_delete.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/template/ent/pet_query.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/template/ent/pet_update.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/template/ent/pet.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/template/ent/tx.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/template/ent/user_create.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/template/ent/user_delete.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/template/ent/user_query.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/template/ent/user_update.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/template/ent/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/template/ent/group/group.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/template/ent/group/where.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/template/ent/migrate/migrate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/template/ent/migrate/schema.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/template/ent/pet/pet.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/template/ent/pet/where.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/template/ent/predicate/predicate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/template/ent/schema/group.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/template/ent/schema/pet.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/template/ent/schema/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/template/ent/template/client.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/template/ent/template/node.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/template/ent/user/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/integration/template/ent/user/where.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/load/load_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/load/load.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/load/schema_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/load/schema.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/load/internal/bindata.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/load/template/main.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/load/testdata/base/schema.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/load/testdata/failure/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/load/testdata/invalid/schema.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/entc/load/testdata/valid/schema.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/README.md
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/edgeindex/edgeindex.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/edgeindex/README.md
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/edgeindex/ent/city_create.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/edgeindex/ent/city_delete.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/edgeindex/ent/city_query.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/edgeindex/ent/city_update.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/edgeindex/ent/city.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/edgeindex/ent/client.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/edgeindex/ent/config.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/edgeindex/ent/context.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/edgeindex/ent/ent.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/edgeindex/ent/example_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/edgeindex/ent/generate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/edgeindex/ent/street_create.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/edgeindex/ent/street_delete.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/edgeindex/ent/street_query.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/edgeindex/ent/street_update.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/edgeindex/ent/street.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/edgeindex/ent/tx.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/edgeindex/ent/city/city.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/edgeindex/ent/city/where.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/edgeindex/ent/migrate/migrate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/edgeindex/ent/migrate/schema.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/edgeindex/ent/predicate/predicate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/edgeindex/ent/schema/city.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/edgeindex/ent/schema/street.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/edgeindex/ent/street/street.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/edgeindex/ent/street/where.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/entcpkg/entcpkg.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/entcpkg/README.md
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/entcpkg/ent/client.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/entcpkg/ent/config.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/entcpkg/ent/context.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/entcpkg/ent/ent.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/entcpkg/ent/entc.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/entcpkg/ent/example_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/entcpkg/ent/generate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/entcpkg/ent/tx.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/entcpkg/ent/user_create.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/entcpkg/ent/user_delete.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/entcpkg/ent/user_query.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/entcpkg/ent/user_update.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/entcpkg/ent/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/entcpkg/ent/migrate/migrate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/entcpkg/ent/migrate/schema.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/entcpkg/ent/predicate/predicate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/entcpkg/ent/schema/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/entcpkg/ent/user/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/entcpkg/ent/user/where.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2m2types/m2m2types.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2m2types/README.md
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2m2types/ent/client.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2m2types/ent/config.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2m2types/ent/context.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2m2types/ent/ent.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2m2types/ent/example_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2m2types/ent/generate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2m2types/ent/group_create.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2m2types/ent/group_delete.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2m2types/ent/group_query.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2m2types/ent/group_update.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2m2types/ent/group.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2m2types/ent/tx.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2m2types/ent/user_create.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2m2types/ent/user_delete.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2m2types/ent/user_query.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2m2types/ent/user_update.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2m2types/ent/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2m2types/ent/group/group.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2m2types/ent/group/where.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2m2types/ent/migrate/migrate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2m2types/ent/migrate/schema.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2m2types/ent/predicate/predicate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2m2types/ent/schema/group.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2m2types/ent/schema/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2m2types/ent/user/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2m2types/ent/user/where.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2mbidi/m2mbidi.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2mbidi/README.md
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2mbidi/ent/client.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2mbidi/ent/config.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2mbidi/ent/context.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2mbidi/ent/ent.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2mbidi/ent/example_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2mbidi/ent/generate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2mbidi/ent/tx.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2mbidi/ent/user_create.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2mbidi/ent/user_delete.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2mbidi/ent/user_query.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2mbidi/ent/user_update.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2mbidi/ent/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2mbidi/ent/migrate/migrate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2mbidi/ent/migrate/schema.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2mbidi/ent/predicate/predicate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2mbidi/ent/schema/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2mbidi/ent/user/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2mbidi/ent/user/where.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2mrecur/m2mrecur.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2mrecur/README.md
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2mrecur/ent/client.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2mrecur/ent/config.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2mrecur/ent/context.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2mrecur/ent/ent.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2mrecur/ent/example_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2mrecur/ent/generate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2mrecur/ent/tx.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2mrecur/ent/user_create.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2mrecur/ent/user_delete.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2mrecur/ent/user_query.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2mrecur/ent/user_update.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2mrecur/ent/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2mrecur/ent/migrate/migrate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2mrecur/ent/migrate/schema.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2mrecur/ent/predicate/predicate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2mrecur/ent/schema/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2mrecur/ent/user/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/m2mrecur/ent/user/where.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2m2types/o2m2types.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2m2types/README.md
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2m2types/ent/client.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2m2types/ent/config.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2m2types/ent/context.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2m2types/ent/ent.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2m2types/ent/example_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2m2types/ent/generate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2m2types/ent/pet_create.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2m2types/ent/pet_delete.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2m2types/ent/pet_query.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2m2types/ent/pet_update.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2m2types/ent/pet.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2m2types/ent/tx.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2m2types/ent/user_create.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2m2types/ent/user_delete.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2m2types/ent/user_query.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2m2types/ent/user_update.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2m2types/ent/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2m2types/ent/migrate/migrate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2m2types/ent/migrate/schema.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2m2types/ent/pet/pet.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2m2types/ent/pet/where.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2m2types/ent/predicate/predicate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2m2types/ent/schema/pet.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2m2types/ent/schema/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2m2types/ent/user/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2m2types/ent/user/where.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2mrecur/o2mrecur.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2mrecur/README.md
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2mrecur/ent/client.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2mrecur/ent/config.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2mrecur/ent/context.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2mrecur/ent/ent.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2mrecur/ent/example_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2mrecur/ent/generate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2mrecur/ent/node_create.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2mrecur/ent/node_delete.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2mrecur/ent/node_query.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2mrecur/ent/node_update.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2mrecur/ent/node.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2mrecur/ent/tx.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2mrecur/ent/migrate/migrate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2mrecur/ent/migrate/schema.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2mrecur/ent/node/node.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2mrecur/ent/node/where.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2mrecur/ent/predicate/predicate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2mrecur/ent/schema/node.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2o2types/o2o2types.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2o2types/README.md
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2o2types/ent/card_create.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2o2types/ent/card_delete.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2o2types/ent/card_query.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2o2types/ent/card_update.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2o2types/ent/card.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2o2types/ent/client.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2o2types/ent/config.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2o2types/ent/context.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2o2types/ent/ent.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2o2types/ent/example_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2o2types/ent/generate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2o2types/ent/tx.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2o2types/ent/user_create.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2o2types/ent/user_delete.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2o2types/ent/user_query.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2o2types/ent/user_update.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2o2types/ent/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2o2types/ent/card/card.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2o2types/ent/card/where.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2o2types/ent/migrate/migrate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2o2types/ent/migrate/schema.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2o2types/ent/predicate/predicate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2o2types/ent/schema/card.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2o2types/ent/schema/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2o2types/ent/user/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2o2types/ent/user/where.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2obidi/o2obidi.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2obidi/README.md
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2obidi/ent/client.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2obidi/ent/config.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2obidi/ent/context.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2obidi/ent/ent.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2obidi/ent/example_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2obidi/ent/generate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2obidi/ent/tx.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2obidi/ent/user_create.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2obidi/ent/user_delete.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2obidi/ent/user_query.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2obidi/ent/user_update.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2obidi/ent/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2obidi/ent/migrate/migrate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2obidi/ent/migrate/schema.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2obidi/ent/predicate/predicate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2obidi/ent/schema/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2obidi/ent/user/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2obidi/ent/user/where.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2orecur/o2orecur.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2orecur/README.md
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2orecur/ent/client.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2orecur/ent/config.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2orecur/ent/context.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2orecur/ent/ent.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2orecur/ent/example_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2orecur/ent/generate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2orecur/ent/node_create.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2orecur/ent/node_delete.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2orecur/ent/node_query.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2orecur/ent/node_update.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2orecur/ent/node.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2orecur/ent/tx.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2orecur/ent/migrate/migrate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2orecur/ent/migrate/schema.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2orecur/ent/node/node.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2orecur/ent/node/where.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2orecur/ent/predicate/predicate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/o2orecur/ent/schema/node.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/start/README.md
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/start/start.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/start/ent/car_create.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/start/ent/car_delete.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/start/ent/car_query.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/start/ent/car_update.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/start/ent/car.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/start/ent/client.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/start/ent/config.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/start/ent/context.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/start/ent/ent.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/start/ent/example_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/start/ent/generate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/start/ent/group_create.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/start/ent/group_delete.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/start/ent/group_query.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/start/ent/group_update.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/start/ent/group.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/start/ent/tx.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/start/ent/user_create.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/start/ent/user_delete.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/start/ent/user_query.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/start/ent/user_update.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/start/ent/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/start/ent/car/car.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/start/ent/car/where.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/start/ent/group/group.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/start/ent/group/where.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/start/ent/migrate/migrate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/start/ent/migrate/schema.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/start/ent/predicate/predicate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/start/ent/schema/car.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/start/ent/schema/group.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/start/ent/schema/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/start/ent/user/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/start/ent/user/where.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/traversal/README.md
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/traversal/traversal.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/traversal/ent/client.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/traversal/ent/config.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/traversal/ent/context.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/traversal/ent/ent.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/traversal/ent/example_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/traversal/ent/generate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/traversal/ent/group_create.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/traversal/ent/group_delete.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/traversal/ent/group_query.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/traversal/ent/group_update.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/traversal/ent/group.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/traversal/ent/pet_create.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/traversal/ent/pet_delete.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/traversal/ent/pet_query.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/traversal/ent/pet_update.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/traversal/ent/pet.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/traversal/ent/tx.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/traversal/ent/user_create.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/traversal/ent/user_delete.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/traversal/ent/user_query.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/traversal/ent/user_update.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/traversal/ent/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/traversal/ent/group/group.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/traversal/ent/group/where.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/traversal/ent/migrate/migrate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/traversal/ent/migrate/schema.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/traversal/ent/pet/pet.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/traversal/ent/pet/where.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/traversal/ent/predicate/predicate.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/traversal/ent/schema/group.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/traversal/ent/schema/pet.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/traversal/ent/schema/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/traversal/ent/user/user.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/examples/traversal/ent/user/where.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/schema/edge/edge_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/schema/edge/edge.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/schema/field/field_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/schema/field/field.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/schema/field/numeric.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/schema/field/type.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/schema/field/gen/gen.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/schema/field/gen/numeric.tmpl
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/schema/index/index_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/schema/index/index.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/schema/schemautil/time_test.go
+pkg/mod/github.com/facebookincubator/ent@v0.0.0-20191128071424-29c7b0a0d805/schema/schemautil/time.go
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/.codecov.yml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/.gitignore
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/.golangci.yml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/.travis.yml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/analyzer_test.go
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/analyzer.go
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/appveyor.yml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/CODE_OF_CONDUCT.md
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/debug_test.go
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/debug.go
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/doc_test.go
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/doc.go
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixer_test.go
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixer.go
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/flatten_test.go
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/flatten.go
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/go.mod
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/go.sum
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/LICENSE
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/mixin_test.go
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/mixin.go
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/README.md
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/schema_test.go
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/schema.go
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/.github/CONTRIBUTING.md
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/allOf.yml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bar-crud.yml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/definitions.yml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/empty-paths.json
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/empty-props.yml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/enums.yml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/errors.yml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/external_definitions_valid.yml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/external_definitions.yml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/fixture-342-2.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/fixture-342-3.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/fixture-342.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/fixture-1289-param.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/flatten.yml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/foo-crud.yml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/inline_schemas.yml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/more_nested_inline_schemas.yml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/nested_inline_schemas.yml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/no-paths.yml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/other-mixin.yml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/patterns.yml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/references.yml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/securitydef.yml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/swagger-props.yml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/widget-crud.yml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/bitbucket.json
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/1429/responses.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/1429/swagger.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/1429/remote/remote.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/1429/remote/remote/remote.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/1602/fixture-1602-1.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/1602/fixture-1602-2.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/1602/fixture-1602-3.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/1602/fixture-1602-4.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/1602/fixture-1602-5.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/1602/fixture-1602-6.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/1602/fixture-1602-full.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/1602/other-invalid-pointers.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/1614/gitea.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/1621/definitions.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/1621/fixture-1621.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/1621/parameters.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/1621/responses.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/1767/fixture-1767.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/1767/Identifier.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/1767/Patient.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/1767/Reference.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/1774/AccessToken.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/1774/Credentials.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/1774/Data.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/1774/def_api.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/1774/Error.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/1774/parameters.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/1774/responses.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/1774/Roles.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/1774/User.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/1774/Users.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/1796/queryIssue.json
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/1796/models/pair.json
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/1796/models/query.json
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/1851/definitions-3.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/1851/definitions-31.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/1851/definitions.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/1851/fixture-1851-2.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/1851/fixture-1851-3.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/1851/fixture-1851.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/1851/remote/definitions-32.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/remote-absolute/ce_v0_2_without_data.json
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/remote-absolute/remote-spec.json
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/remote-absolute/swagger-mini.json
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/remote-absolute/swagger-with-local-ref.json
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/remote-absolute/swagger-with-ref.json
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/remote-absolute/swagger-with-remote-only-ref.json
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/bugs/remote-absolute/swagger.json
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/errors/fixture-unexpandable-2.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/errors/fixture-unexpandable.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/external/definitions.yml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/external/definitions2.yml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/external/errors.yml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/external/nestedParams.yml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/external/nestedResponses.yml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/external/parameters.yml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/external/pathItem.yml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/external/responses.yml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/fixer/fixer.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/oaigen/fixture-oaigen.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/oaigen/test3-bis-swagger.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/oaigen/test3-model-schema.json
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/oaigen/test3-swagger.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/oaigen/test3-ter-model-schema.json
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/oaigen/test3-ter-swagger-flat.json
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/oaigen/test3-ter-swagger.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/oaigen/transitive-1.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/oaigen/transitive-2.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/operations/fixture-operations.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/parameters/fixture-parameters.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/parameters/other-source.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/pointers/fixture-pointers-loop.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/pointers/fixture-pointers.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/fixtures/pointers/remote.yaml
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/internal/path_unescape_test.go
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/internal/post_go18.go
+pkg/mod/github.com/go-openapi/analysis@v0.19.5/internal/pre_go18.go
+pkg/mod/github.com/go-openapi/errors@v0.19.2/.gitignore
+pkg/mod/github.com/go-openapi/errors@v0.19.2/.golangci.yml
+pkg/mod/github.com/go-openapi/errors@v0.19.2/.travis.yml
+pkg/mod/github.com/go-openapi/errors@v0.19.2/api_test.go
+pkg/mod/github.com/go-openapi/errors@v0.19.2/api.go
+pkg/mod/github.com/go-openapi/errors@v0.19.2/auth_test.go
+pkg/mod/github.com/go-openapi/errors@v0.19.2/auth.go
+pkg/mod/github.com/go-openapi/errors@v0.19.2/CODE_OF_CONDUCT.md
+pkg/mod/github.com/go-openapi/errors@v0.19.2/doc.go
+pkg/mod/github.com/go-openapi/errors@v0.19.2/go.mod
+pkg/mod/github.com/go-openapi/errors@v0.19.2/go.sum
+pkg/mod/github.com/go-openapi/errors@v0.19.2/headers.go
+pkg/mod/github.com/go-openapi/errors@v0.19.2/LICENSE
+pkg/mod/github.com/go-openapi/errors@v0.19.2/middleware_test.go
+pkg/mod/github.com/go-openapi/errors@v0.19.2/middleware.go
+pkg/mod/github.com/go-openapi/errors@v0.19.2/parsing_test.go
+pkg/mod/github.com/go-openapi/errors@v0.19.2/parsing.go
+pkg/mod/github.com/go-openapi/errors@v0.19.2/README.md
+pkg/mod/github.com/go-openapi/errors@v0.19.2/schema_test.go
+pkg/mod/github.com/go-openapi/errors@v0.19.2/schema.go
+pkg/mod/github.com/go-openapi/errors@v0.19.2/.github/CONTRIBUTING.md
+pkg/mod/github.com/go-openapi/jsonpointer@v0.19.3/.editorconfig
+pkg/mod/github.com/go-openapi/jsonpointer@v0.19.3/.gitignore
+pkg/mod/github.com/go-openapi/jsonpointer@v0.19.3/.travis.yml
+pkg/mod/github.com/go-openapi/jsonpointer@v0.19.3/CODE_OF_CONDUCT.md
+pkg/mod/github.com/go-openapi/jsonpointer@v0.19.3/go.mod
+pkg/mod/github.com/go-openapi/jsonpointer@v0.19.3/go.sum
+pkg/mod/github.com/go-openapi/jsonpointer@v0.19.3/LICENSE
+pkg/mod/github.com/go-openapi/jsonpointer@v0.19.3/pointer_test.go
+pkg/mod/github.com/go-openapi/jsonpointer@v0.19.3/pointer.go
+pkg/mod/github.com/go-openapi/jsonpointer@v0.19.3/README.md
+pkg/mod/github.com/go-openapi/jsonpointer@v0.19.3/.github/CONTRIBUTING.md
+pkg/mod/github.com/go-openapi/jsonreference@v0.19.2/.gitignore
+pkg/mod/github.com/go-openapi/jsonreference@v0.19.2/.travis.yml
+pkg/mod/github.com/go-openapi/jsonreference@v0.19.2/CODE_OF_CONDUCT.md
+pkg/mod/github.com/go-openapi/jsonreference@v0.19.2/go.mod
+pkg/mod/github.com/go-openapi/jsonreference@v0.19.2/go.sum
+pkg/mod/github.com/go-openapi/jsonreference@v0.19.2/LICENSE
+pkg/mod/github.com/go-openapi/jsonreference@v0.19.2/README.md
+pkg/mod/github.com/go-openapi/jsonreference@v0.19.2/reference_test.go
+pkg/mod/github.com/go-openapi/jsonreference@v0.19.2/reference.go
+pkg/mod/github.com/go-openapi/jsonreference@v0.19.2/.github/CONTRIBUTING.md
+pkg/mod/github.com/go-openapi/loads@v0.19.3/.editorconfig
+pkg/mod/github.com/go-openapi/loads@v0.19.3/.gitignore
+pkg/mod/github.com/go-openapi/loads@v0.19.3/.golangci.yml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/.travis.yml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/CODE_OF_CONDUCT.md
+pkg/mod/github.com/go-openapi/loads@v0.19.3/doc.go
+pkg/mod/github.com/go-openapi/loads@v0.19.3/go.mod
+pkg/mod/github.com/go-openapi/loads@v0.19.3/go.sum
+pkg/mod/github.com/go-openapi/loads@v0.19.3/json_test.go
+pkg/mod/github.com/go-openapi/loads@v0.19.3/LICENSE
+pkg/mod/github.com/go-openapi/loads@v0.19.3/README.md
+pkg/mod/github.com/go-openapi/loads@v0.19.3/spec_test.go
+pkg/mod/github.com/go-openapi/loads@v0.19.3/spec.go
+pkg/mod/github.com/go-openapi/loads@v0.19.3/.github/CONTRIBUTING.md
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/bugs/1816/fixture-1816.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/models/models.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/models/modelWithArrayRef.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/models/modelWithComposition.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/models/modelWithDateTimeMap.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/models/modelWithExamples.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/models/modelWithInt32Map.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/models/modelWithInt64Map.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/models/modelWithMultipleProperties.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/models/modelWithObjectMap.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/models/modelWithPrimitiveArray.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/models/modelWithStringProperty.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/models/modelWithXmlAttributes.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/models/multipleModels.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/models/properties/propertyWithBooleanArray.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/models/properties/propertyWithByteArray.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/models/properties/propertyWithComplexArray.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/models/properties/propertyWithDateTimeArray.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/models/properties/propertyWithInt32Array.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/models/properties/propertyWithInt64Array.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/models/properties/propertyWithRef.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/models/properties/propertyWithStringArray.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/models/properties/simpleBooleanProperty.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/models/properties/simpleByteProperty.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/models/properties/simpleDateTimeProperty.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/models/properties/simpleInt32Property.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/models/properties/simpleInt64Property.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/models/properties/simpleStringProperty.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/resources/cascadingSchemes.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/resources/commonParameters.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/resources/multipleMimeTypes.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/resources/resourceWithExamplePayload.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/resources/resourceWithLinkedDefinitions_part1.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/resources/resourceWithLinkedDefinitions.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/resources/resourceWithRelativeHost.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/resources/reusableParameters.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/resources/securityExample.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/resources/stringPathParamResource.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/resources/taggedResource.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/resources/vendorExtensionExamples.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/resources/operations/operationWithTags.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/resources/operations/stringPathAndBoolQueryParamResource.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/resources/operations/stringPathParamResource.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/resources/parameters/bodyComplexArrayParameter.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/resources/parameters/bodyComplexParameter.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/resources/parameters/bodyInt64Parameter.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/resources/parameters/bodyStringArrayParameter.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/resources/parameters/bodyStringParameter.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/resources/parameters/formDataComplexParameter.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/resources/parameters/formDataInt64Parameter.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/resources/parameters/formDataStringArrayParameter.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/resources/parameters/formDataStringParameter.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/resources/parameters/headerInt64ArrayParameter.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/resources/parameters/headerStringArrayParameter.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/resources/parameters/headerStringParameter.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/resources/parameters/pathInt64Parameter.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/resources/parameters/pathStringArrayParameter.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/resources/parameters/pathStringParameter.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/resources/parameters/queryInt64ArrayParameter.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/resources/parameters/queryStringParameter.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/resources/parameters/queryWithComplexParameter.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/responses/complexArrayResponse.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/responses/dateTimeResponse.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/responses/int32Response.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/responses/int64Response.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/responses/multipleResponses.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/responses/stringArrayResponse.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/responses/stringResponse.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/responses/stringResponseWithHeader.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/json/responses/voidResponse.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/.gitkeep
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/models/models.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/models/modelWithArrayRef.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/models/modelWithComposition.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/models/modelWithDateTimeMap.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/models/modelWithExamples.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/models/modelWithInt32Map.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/models/modelWithInt64Map.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/models/modelWithMultipleProperties.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/models/modelWithObjectMap.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/models/modelWithPrimitiveArray.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/models/modelWithStringProperty.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/models/modelWithXmlAttributes.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/models/multipleModels.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/models/properties/propertyWithBooleanArray.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/models/properties/propertyWithByteArray.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/models/properties/propertyWithComplexArray.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/models/properties/propertyWithDateTimeArray.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/models/properties/propertyWithInt32Array.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/models/properties/propertyWithInt64Array.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/models/properties/propertyWithRef.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/models/properties/propertyWithStringArray.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/models/properties/simpleBooleanProperty.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/models/properties/simpleByteProperty.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/models/properties/simpleDateTimeProperty.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/models/properties/simpleInt32Property.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/models/properties/simpleInt64Property.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/models/properties/simpleStringProperty.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/resources/cascadingSchemes.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/resources/commonParameters.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/resources/multipleMimeTypes.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/resources/resourceWithExamplePayload.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/resources/resourceWithLinkedDefinitions_part1.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/resources/resourceWithLinkedDefinitions.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/resources/resourceWithRelativeHost.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/resources/reusableParameters.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/resources/securityExample.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/resources/stringPathParamResource.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/resources/taggedResource.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/resources/vendorExtensionExamples.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/resources/operations/operationWithTags.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/resources/operations/stringPathAndBoolQueryParamResource.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/resources/operations/stringPathParamResource.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/resources/parameters/bodyComplexArrayParameter.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/resources/parameters/bodyComplexParameter.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/resources/parameters/bodyInt64Parameter.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/resources/parameters/bodyStringArrayParameter.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/resources/parameters/bodyStringParameter.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/resources/parameters/formDataComplexParameter.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/resources/parameters/formDataInt64Parameter.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/resources/parameters/formDataStringArrayParameter.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/resources/parameters/formDataStringParameter.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/resources/parameters/headerInt64ArrayParameter.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/resources/parameters/headerStringArrayParameter.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/resources/parameters/headerStringParameter.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/resources/parameters/pathInt64Parameter.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/resources/parameters/pathStringArrayParameter.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/resources/parameters/pathStringParameter.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/resources/parameters/queryInt64ArrayParameter.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/resources/parameters/queryStringParameter.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/resources/parameters/queryWithComplexParameter.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/responses/complexArrayResponse.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/responses/dateTimeResponse.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/responses/int32Response.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/responses/int64Response.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/responses/multipleResponses.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/responses/stringArrayResponse.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/responses/stringResponse.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/responses/stringResponseWithHeader.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/responses/voidResponse.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/swagger/spec.yml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/swagger/test3-ter-model-schema.json
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/swagger/1/2/3/4/swagger.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/swagger/shared/something.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/swagger/shared/definitions/page.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/.gitkeep
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/models/models.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/models/modelWithArrayRef.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/models/modelWithComposition.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/models/modelWithDateTimeMap.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/models/modelWithExamples.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/models/modelWithInt32Map.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/models/modelWithInt64Map.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/models/modelWithMultipleProperties.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/models/modelWithObjectMap.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/models/modelWithPrimitiveArray.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/models/modelWithStringProperty.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/models/modelWithXmlAttributes.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/models/multipleModels.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/models/properties/propertyWithBooleanArray.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/models/properties/propertyWithByteArray.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/models/properties/propertyWithComplexArray.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/models/properties/propertyWithDateTimeArray.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/models/properties/propertyWithInt32Array.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/models/properties/propertyWithInt64Array.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/models/properties/propertyWithRef.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/models/properties/propertyWithStringArray.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/models/properties/simpleBooleanProperty.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/models/properties/simpleByteProperty.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/models/properties/simpleDateTimeProperty.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/models/properties/simpleInt32Property.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/models/properties/simpleInt64Property.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/models/properties/simpleStringProperty.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/resources/cascadingSchemes.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/resources/commonParameters.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/resources/multipleMimeTypes.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/resources/resourceWithExamplePayload.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/resources/resourceWithLinkedDefinitions_part1.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/resources/resourceWithLinkedDefinitions.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/resources/resourceWithRelativeHost.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/resources/reusableParameters.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/resources/securityExample.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/resources/stringPathParamResource.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/resources/taggedResource.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/resources/vendorExtensionExamples.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/resources/operations/operationWithTags.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/resources/operations/stringPathAndBoolQueryParamResource.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/resources/operations/stringPathParamResource.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/resources/parameters/bodyComplexArrayParameter.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/resources/parameters/bodyComplexParameter.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/resources/parameters/bodyInt64Parameter.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/resources/parameters/bodyStringArrayParameter.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/resources/parameters/bodyStringParameter.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/resources/parameters/formDataComplexParameter.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/resources/parameters/formDataInt64Parameter.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/resources/parameters/formDataStringArrayParameter.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/resources/parameters/formDataStringParameter.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/resources/parameters/headerInt64ArrayParameter.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/resources/parameters/headerStringArrayParameter.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/resources/parameters/headerStringParameter.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/resources/parameters/pathInt64Parameter.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/resources/parameters/pathStringArrayParameter.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/resources/parameters/pathStringParameter.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/resources/parameters/queryInt64ArrayParameter.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/resources/parameters/queryStringParameter.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/resources/parameters/queryWithComplexParameter.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/responses/complexArrayResponse.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/responses/dateTimeResponse.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/responses/int32Response.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/responses/int64Response.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/responses/multipleResponses.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/responses/stringArrayResponse.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/responses/stringResponse.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/responses/stringResponseWithHeader.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fixtures/yaml/yaml/responses/voidResponse.yaml
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fmts/fixture_test.go
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fmts/yaml_test.go
+pkg/mod/github.com/go-openapi/loads@v0.19.3/fmts/yaml.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/.editorconfig
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/.gitignore
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/.travis.yml
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/authinfo_test.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/bytestream_test.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/bytestream.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/client_auth_info.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/client_operation.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/client_request_test.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/client_request.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/client_response_test.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/client_response.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/CODE_OF_CONDUCT.md
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/constants.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/csv_test.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/csv.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/discard.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/file_test.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/file.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/go.mod
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/go.sum
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/headers_test.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/headers.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/interfaces.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/json_test.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/json.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/LICENSE
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/README.md
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/request_test.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/request.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/statuses.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/text_test.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/text.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/values.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/xml_test.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/xml.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/.github/CONTRIBUTING.md
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/client/auth_info_test.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/client/auth_info.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/client/keepalive_test.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/client/keepalive.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/client/request_test.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/client/request.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/client/response_test.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/client/response.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/client/runtime_test.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/client/runtime.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/fixtures/bugs/264/swagger.yml
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/fixtures/certs/myCA.crt
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/fixtures/certs/myCA.key
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/fixtures/certs/mycert1.crt
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/fixtures/certs/mycert1.key
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/fixtures/certs/mycert1.req
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/fixtures/certs/myclient-ecc.crt
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/fixtures/certs/myclient-ecc.csr
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/fixtures/certs/myclient-ecc.key
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/fixtures/certs/myclient.crt
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/fixtures/certs/myclient.csr
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/fixtures/certs/myclient.key
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/fixtures/certs/myclient.p12
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/fixtures/certs/serial
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/flagext/byte_size_test.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/flagext/byte_size.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/hack/gen-self-signed-certs.sh
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/internal/testing/data.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/internal/testing/petstore/api.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/internal/testing/simplepetstore/api_test.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/internal/testing/simplepetstore/api.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/logger/logger.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/logger/standard.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/middleware/body_test.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/middleware/context_test.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/middleware/context.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/middleware/doc.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/middleware/go18.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/middleware/negotiate_test.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/middleware/negotiate.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/middleware/not_implemented.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/middleware/operation_test.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/middleware/operation.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/middleware/parameter_test.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/middleware/parameter.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/middleware/pre_go18.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/middleware/redoc_test.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/middleware/redoc.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/middleware/request_test.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/middleware/request.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/middleware/route_authenticator_test.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/middleware/route_param_test.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/middleware/router_test.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/middleware/router.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/middleware/security_test.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/middleware/security.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/middleware/spec_test.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/middleware/spec.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/middleware/string_conversion_test.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/middleware/untyped_request_test.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/middleware/validation_test.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/middleware/validation.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/middleware/denco/LICENSE
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/middleware/denco/README.md
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/middleware/denco/router_bench_test.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/middleware/denco/router_test.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/middleware/denco/router.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/middleware/denco/server_test.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/middleware/denco/server.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/middleware/denco/util_test.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/middleware/denco/util.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/middleware/header/header.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/middleware/untyped/api_test.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/middleware/untyped/api.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/security/apikey_auth_test.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/security/authenticator.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/security/authorizer_test.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/security/authorizer.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/security/basic_auth_test.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/security/bearer_auth_test.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/yamlpc/yaml_test.go
+pkg/mod/github.com/go-openapi/runtime@v0.19.5/yamlpc/yaml.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/.editorconfig
+pkg/mod/github.com/go-openapi/spec@v0.19.3/.gitignore
+pkg/mod/github.com/go-openapi/spec@v0.19.3/.golangci.yml
+pkg/mod/github.com/go-openapi/spec@v0.19.3/.travis.yml
+pkg/mod/github.com/go-openapi/spec@v0.19.3/auth_test.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/bindata.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/cache.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/CODE_OF_CONDUCT.md
+pkg/mod/github.com/go-openapi/spec@v0.19.3/contact_info_test.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/contact_info.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/debug_test.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/debug.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/expander_test.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/expander.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/external_docs_test.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/external_docs.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/go.mod
+pkg/mod/github.com/go-openapi/spec@v0.19.3/go.sum
+pkg/mod/github.com/go-openapi/spec@v0.19.3/header_test.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/header.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/info_test.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/info.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/items_test.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/items.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/LICENSE
+pkg/mod/github.com/go-openapi/spec@v0.19.3/license_test.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/license.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/normalizer.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/operation_test.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/operation.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/parameter.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/parameters_test.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/path_item_test.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/path_item.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/paths_test.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/paths.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/properties_test.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/README.md
+pkg/mod/github.com/go-openapi/spec@v0.19.3/ref_test.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/ref.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/response_test.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/response.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/responses.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/schema_loader.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/schema_test.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/schema.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/security_scheme.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/spec_test.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/spec.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/structs_test.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/swagger_test.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/swagger.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/tag.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/unused.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/xml_object_test.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/xml_object.go
+pkg/mod/github.com/go-openapi/spec@v0.19.3/.github/CONTRIBUTING.md
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/bugs/1429/responses.yaml
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/bugs/1429/swagger.yaml
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/bugs/1429/remote/remote.yaml
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/bugs/1429/remote/farther/farther.yaml
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/bugs/1429/remote/remote/remote.yaml
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/bugs/1614/gitea.json
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/bugs/1621/definitions.yaml
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/bugs/1621/fixture-1621.yaml
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/bugs/1621/parameters.yaml
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/bugs/1621/responses.yaml
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/bugs/69/dapperbox.json
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/bugs/957/fixture-957.json
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/expansion/all-the-things.json
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/expansion/circular-minimal.json
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/expansion/circularRefs.json
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/expansion/circularSpec.json
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/expansion/circularSpec.yaml
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/expansion/circularSpec2.json
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/expansion/clickmeter.json
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/expansion/clickmeter.yaml
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/expansion/extraRef.json
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/expansion/invalid-refs.json
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/expansion/missingItemRef.json
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/expansion/missingRef.json
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/expansion/overflow.json
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/expansion/params.json
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/expansion/pathItem1.json
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/expansion/pathItems.json
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/expansion/schemas1.json
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/expansion/schemas2.json
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/local_expansion/item.json
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/local_expansion/item2.yaml
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/local_expansion/spec.json
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/local_expansion/spec2.yaml
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/more_circulars/bitbucket.json
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/more_circulars/item.json
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/more_circulars/item2.json
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/more_circulars/item4.json
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/more_circulars/spec.json
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/more_circulars/spec2.json
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/more_circulars/spec3.json
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/more_circulars/spec4.json
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/remote/all-the-things.json
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/remote/pet/pet.json
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/specs/refed.json
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/specs/resolution.json
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/specs/resolution2.json
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/specs/todos.common.json
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/specs/todos.json
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/specs/deeper/arrayProp.json
+pkg/mod/github.com/go-openapi/spec@v0.19.3/fixtures/specs/deeper/stringProp.json
+pkg/mod/github.com/go-openapi/spec@v0.19.3/schemas/jsonschema-draft-04.json
+pkg/mod/github.com/go-openapi/spec@v0.19.3/schemas/v2/README.md
+pkg/mod/github.com/go-openapi/spec@v0.19.3/schemas/v2/schema.json
+pkg/mod/github.com/go-openapi/strfmt@v0.19.4/.editorconfig
+pkg/mod/github.com/go-openapi/strfmt@v0.19.4/.gitignore
+pkg/mod/github.com/go-openapi/strfmt@v0.19.4/.golangci.yml
+pkg/mod/github.com/go-openapi/strfmt@v0.19.4/.travis.yml
+pkg/mod/github.com/go-openapi/strfmt@v0.19.4/bson_test.go
+pkg/mod/github.com/go-openapi/strfmt@v0.19.4/bson.go
+pkg/mod/github.com/go-openapi/strfmt@v0.19.4/CODE_OF_CONDUCT.md
+pkg/mod/github.com/go-openapi/strfmt@v0.19.4/date_test.go
+pkg/mod/github.com/go-openapi/strfmt@v0.19.4/date.go
+pkg/mod/github.com/go-openapi/strfmt@v0.19.4/default_test.go
+pkg/mod/github.com/go-openapi/strfmt@v0.19.4/default.go
+pkg/mod/github.com/go-openapi/strfmt@v0.19.4/doc.go
+pkg/mod/github.com/go-openapi/strfmt@v0.19.4/duration_test.go
+pkg/mod/github.com/go-openapi/strfmt@v0.19.4/duration.go
+pkg/mod/github.com/go-openapi/strfmt@v0.19.4/format_test.go
+pkg/mod/github.com/go-openapi/strfmt@v0.19.4/format.go
+pkg/mod/github.com/go-openapi/strfmt@v0.19.4/go.mod
+pkg/mod/github.com/go-openapi/strfmt@v0.19.4/go.sum
+pkg/mod/github.com/go-openapi/strfmt@v0.19.4/LICENSE
+pkg/mod/github.com/go-openapi/strfmt@v0.19.4/README.md
+pkg/mod/github.com/go-openapi/strfmt@v0.19.4/time_test.go
+pkg/mod/github.com/go-openapi/strfmt@v0.19.4/time.go
+pkg/mod/github.com/go-openapi/strfmt@v0.19.4/.github/CONTRIBUTING.md
+pkg/mod/github.com/go-openapi/strfmt@v0.19.4/conv/date_test.go
+pkg/mod/github.com/go-openapi/strfmt@v0.19.4/conv/date.go
+pkg/mod/github.com/go-openapi/strfmt@v0.19.4/conv/default_test.go
+pkg/mod/github.com/go-openapi/strfmt@v0.19.4/conv/default.go
+pkg/mod/github.com/go-openapi/strfmt@v0.19.4/conv/duration_test.go
+pkg/mod/github.com/go-openapi/strfmt@v0.19.4/conv/duration.go
+pkg/mod/github.com/go-openapi/strfmt@v0.19.4/conv/time_test.go
+pkg/mod/github.com/go-openapi/strfmt@v0.19.4/conv/time.go
+pkg/mod/github.com/go-openapi/strfmt@v0.19.4/hack/coverage
+pkg/mod/github.com/go-openapi/swag@v0.19.5/.editorconfig
+pkg/mod/github.com/go-openapi/swag@v0.19.5/.gitignore
+pkg/mod/github.com/go-openapi/swag@v0.19.5/.golangci.yml
+pkg/mod/github.com/go-openapi/swag@v0.19.5/.travis.yml
+pkg/mod/github.com/go-openapi/swag@v0.19.5/CODE_OF_CONDUCT.md
+pkg/mod/github.com/go-openapi/swag@v0.19.5/convert_test.go
+pkg/mod/github.com/go-openapi/swag@v0.19.5/convert_types_test.go
+pkg/mod/github.com/go-openapi/swag@v0.19.5/convert_types.go
+pkg/mod/github.com/go-openapi/swag@v0.19.5/convert.go
+pkg/mod/github.com/go-openapi/swag@v0.19.5/doc.go
+pkg/mod/github.com/go-openapi/swag@v0.19.5/go.mod
+pkg/mod/github.com/go-openapi/swag@v0.19.5/go.sum
+pkg/mod/github.com/go-openapi/swag@v0.19.5/json_test.go
+pkg/mod/github.com/go-openapi/swag@v0.19.5/json.go
+pkg/mod/github.com/go-openapi/swag@v0.19.5/LICENSE
+pkg/mod/github.com/go-openapi/swag@v0.19.5/loading_test.go
+pkg/mod/github.com/go-openapi/swag@v0.19.5/loading.go
+pkg/mod/github.com/go-openapi/swag@v0.19.5/name_lexem.go
+pkg/mod/github.com/go-openapi/swag@v0.19.5/net_test.go
+pkg/mod/github.com/go-openapi/swag@v0.19.5/net.go
+pkg/mod/github.com/go-openapi/swag@v0.19.5/path_test.go
+pkg/mod/github.com/go-openapi/swag@v0.19.5/path.go
+pkg/mod/github.com/go-openapi/swag@v0.19.5/post_go18.go
+pkg/mod/github.com/go-openapi/swag@v0.19.5/post_go19.go
+pkg/mod/github.com/go-openapi/swag@v0.19.5/pre_go18.go
+pkg/mod/github.com/go-openapi/swag@v0.19.5/pre_go19.go
+pkg/mod/github.com/go-openapi/swag@v0.19.5/README.md
+pkg/mod/github.com/go-openapi/swag@v0.19.5/split.go
+pkg/mod/github.com/go-openapi/swag@v0.19.5/util_test.go
+pkg/mod/github.com/go-openapi/swag@v0.19.5/util.go
+pkg/mod/github.com/go-openapi/swag@v0.19.5/yaml_test.go
+pkg/mod/github.com/go-openapi/swag@v0.19.5/yaml.go
+pkg/mod/github.com/go-openapi/swag@v0.19.5/.github/CONTRIBUTING.md
+pkg/mod/github.com/go-openapi/validate@v0.19.3/.editorconfig
+pkg/mod/github.com/go-openapi/validate@v0.19.3/.gitignore
+pkg/mod/github.com/go-openapi/validate@v0.19.3/.golangci.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/.travis.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/CODE_OF_CONDUCT.md
+pkg/mod/github.com/go-openapi/validate@v0.19.3/debug_test.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/debug.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/default_validator_test.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/default_validator.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/doc_test.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/doc.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/example_validator_test.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/example_validator.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/formats_test.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/formats.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/go.mod
+pkg/mod/github.com/go-openapi/validate@v0.19.3/go.sum
+pkg/mod/github.com/go-openapi/validate@v0.19.3/helpers_test.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/helpers.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/items_validator_test.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/jsonschema_test.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/LICENSE
+pkg/mod/github.com/go-openapi/validate@v0.19.3/messages_test.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/object_validator_test.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/object_validator.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/options_test.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/options.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/parameter_validator_test.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/README.md
+pkg/mod/github.com/go-openapi/validate@v0.19.3/result_test.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/result.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/rexp_test.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/rexp.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/schema_messages.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/schema_option_test.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/schema_option.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/schema_props_test.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/schema_props.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/schema_test.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/schema.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/slice_validator_test.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/slice_validator.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/spec_messages.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/spec_test.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/spec.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/swagger_test.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/type_test.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/type.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/update-fixtures.sh
+pkg/mod/github.com/go-openapi/validate@v0.19.3/validator_test.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/validator.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/values_test.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/values.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/.github/CONTRIBUTING.md
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/bugs/123/swagger.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/bugs/1341/fixture-1341-2.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/bugs/1341/fixture-1341-3.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/bugs/1341/fixture-1341-4.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/bugs/1341/fixture-1341-5.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/bugs/1341/fixture-1341-good.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/bugs/1341/fixture-1341.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/bugs/1429/expand-1429.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/bugs/1429/flatten-1429.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/bugs/1429/responses.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/bugs/1429/swagger.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/bugs/1614/gitea-expanded.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/bugs/1614/gitea.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/bugs/1621/1621-flat.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/bugs/1621/definitions.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/bugs/1621/fixture-1621.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/bugs/1621/parameters.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/bugs/1621/responses.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/bugs/18/headerItems.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/bugs/18/headers.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/bugs/18/parameters.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/bugs/18/paramItems.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/bugs/18/schema.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/bugs/39/swagger.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/bugs/52/swagger.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/bugs/53/noswagger.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/bugs/6/empty-responses.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/bugs/6/no-responses.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/bugs/61/multiple-refs.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/bugs/61/unresolved-ref-for-name.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/bugs/62/swagger.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/bugs/63/swagger.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/bugs/73/fixture-responses-2.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/bugs/73/fixture-responses-3.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/bugs/73/fixture-responses.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/bugs/73/fixture-swagger-2.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/bugs/73/fixture-swagger-3.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/bugs/73/fixture-swagger-good.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/bugs/73/fixture-swagger.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/defaulting/schema.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/formats/extended-format.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/1010/swagger.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/103/swagger.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/106/swagger.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/1111/arrayParam.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/1171/swagger.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/1199/nonEmptyBody.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/1216/swagger.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/1238/swagger.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/1289/fixture-1289-2.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/1289/fixture-1289-3.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/1289/fixture-1289-4.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/1289/fixture-1289.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/155/swagger.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/162/swagger.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/163/swagger.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/193/spec1.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/193/spec2.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/195/swagger.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/196/swagger.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/217/array.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/217/interface.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/217/map.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/217/string.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/248/swagger.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/249/swagger.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/251/swagger.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/252/swagger.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/287/swagger.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/319/swagger.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/342/fixture-342-2.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/342/fixture-342-3.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/342/fixture-342.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/423/swagger.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/436/swagger.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/453/swagger.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/454/swagger.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/455/swagger.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/465/swagger.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/500/swagger.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/511/swagger.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/524/swagger.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/540/swagger.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/541/swagger.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/628/swagger.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/727/swagger.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/733/swagger.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/740/swagger.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/743/swagger.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/763/swagger.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/774/swagger.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/776/error.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/776/item.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/776/param.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/776/spec.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/776/swagger-template.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/786/swagger.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/789/swagger.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/809/swagger.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/811/swagger.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/822/swagger.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/825/swagger.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/84/swagger.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/844/swagger.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/846/swagger.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/881/deep.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/881/swagger.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/890/swagger.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/890/path/health_check.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/899/swagger.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/981/swagger.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/982/swagger.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/bugs/987/swagger.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/canary/bitbucket.org/swagger.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/canary/docker/swagger.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/canary/kubernetes/swagger.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/canary/ms-cog-sci/swagger.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/canary/petstore/swagger.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/canary/quay.io/swagger.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/expansion/all-the-things.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/expansion/circularRefs.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/expansion/circularSpec.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/expansion/circularSpec.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/expansion/clickmeter.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/expansion/clickmeter.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/expansion/invalid-refs.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/expansion/params.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/expansion/schemas1.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/expansion/schemas2.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/petstores/petstore-expanded.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/petstores/petstore-simple.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/petstores/petstore-with-external-docs.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/petstores/petstore.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/remotes/integer.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/remotes/subSchemas.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/remotes/folder/folderInteger.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/specs/refed.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/specs/resolution.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/specs/resolution2.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/specs/response_name.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/specs/deeper/arrayProp.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/specs/deeper/stringProp.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/go-swagger/templates/swagger_json_embed.gotmpl
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/jsonschema_suite/additionalItems.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/jsonschema_suite/additionalProperties.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/jsonschema_suite/allOf.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/jsonschema_suite/anyOf.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/jsonschema_suite/default.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/jsonschema_suite/definitions.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/jsonschema_suite/dependencies.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/jsonschema_suite/enum.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/jsonschema_suite/format.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/jsonschema_suite/items.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/jsonschema_suite/maximum.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/jsonschema_suite/maxItems.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/jsonschema_suite/maxLength.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/jsonschema_suite/maxProperties.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/jsonschema_suite/minimum.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/jsonschema_suite/minItems.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/jsonschema_suite/minLength.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/jsonschema_suite/minProperties.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/jsonschema_suite/multipleOf.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/jsonschema_suite/not.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/jsonschema_suite/oneOf.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/jsonschema_suite/pattern.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/jsonschema_suite/patternProperties.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/jsonschema_suite/properties.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/jsonschema_suite/ref.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/jsonschema_suite/refRemote.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/jsonschema_suite/required.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/jsonschema_suite/type.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/jsonschema_suite/uniqueItems.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/jsonschema_suite/optional/bignum.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/jsonschema_suite/optional/ecmascript-regex.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/jsonschema_suite/optional/format.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/jsonschema_suite/optional/zeroTerminatedFloats.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/jsonschema_suite/remotes/integer.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/jsonschema_suite/remotes/name.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/jsonschema_suite/remotes/subSchemas.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/jsonschema_suite/remotes/folder/folderInteger.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/local_expansion/item.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/local_expansion/spec.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/pruning/schema.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/recursive_expansion/item.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/recursive_expansion/spec.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/schemas/int-enum.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/bitbucket.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/direct-circular-ancestor.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/duplicateprops.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/empty-path-param-name.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/expected_messages.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-43-2.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-43.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-161-2.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-161-good.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-161.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-342-2.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-342.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-581-good-numbers.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-581-good.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-581-inline-param-format.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-581-inline-param.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-581.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-859-2.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-859-good.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-859.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-1050.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-1171.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-1231.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-1238.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-1243-2.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-1243-3.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-1243-4.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-1243-5.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-1243-5.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-1243-good.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-1243.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-1289-donotload.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-1289-donotload.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-1289-good.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-1289.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-additional-items-2.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-additional-items-3.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-additional-items-invalid-values.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-additional-items.orig
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-additional-items.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-all-formats.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-bad-response.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-collisions.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-constraints-on-numbers.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-empty-paths.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-invalid-example-property.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-items-items.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-no-json-example.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-no-response.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-patternProperties.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/fixture-valid-example-property.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/gentest.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/gentest2.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/gentest3.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/indirect-circular-ancestor.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/invalid-formdata-body-params.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/invalid-ref.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/invalid-referenced.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/nestedduplicateprops.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/petstore-expanded.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/recursive-circular-ancestor.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/valid-ref.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/valid-referenced-variants.yaml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/valid-referenced.yml
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/default/invalid-default-value-default-response-PatternProperties.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/default/invalid-default-value-default-response.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/default/invalid-default-value-header-badpattern.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/default/invalid-default-value-header-items-default-response.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/default/invalid-default-value-header-items-response.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/default/invalid-default-value-header-items.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/default/invalid-default-value-header-pattern.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/default/invalid-default-value-header-response.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/default/invalid-default-value-header.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/default/invalid-default-value-parameter-items.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/default/invalid-default-value-parameter-ref.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/default/invalid-default-value-parameter-required.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/default/invalid-default-value-parameter-schema.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/default/invalid-default-value-parameter.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/default/invalid-default-value-response-ref.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/default/invalid-default-value-schema-additionalProperties.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/default/invalid-default-value-schema-allOf.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/default/invalid-default-value-schema-items-allOf.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/default/invalid-default-value-schema-items.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/default/invalid-default-value-schema-patternProperties.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/default/invalid-default-value-schema-ref.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/default/invalid-default-value-schema.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/default/valid-default-value-default-response-PatternProperties.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/default/valid-default-value-default-response.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/default/valid-default-value-header-badpattern.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/default/valid-default-value-header-items-default-response.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/default/valid-default-value-header-items-response.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/default/valid-default-value-header-items.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/default/valid-default-value-header-pattern.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/default/valid-default-value-header-response.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/default/valid-default-value-header.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/default/valid-default-value-parameter-items.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/default/valid-default-value-parameter-ref.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/default/valid-default-value-parameter-required.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/default/valid-default-value-parameter-schema.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/default/valid-default-value-parameter.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/default/valid-default-value-response-ref.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/default/valid-default-value-schema-additionalProperties.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/default/valid-default-value-schema-allOf.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/default/valid-default-value-schema-items-allOf.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/default/valid-default-value-schema-items.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/default/valid-default-value-schema-patternProperties.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/default/valid-default-value-schema-ref.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/default/valid-default-value-schema.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/invalid-example-default-response-PatternProperties.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/invalid-example-default-response.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/invalid-example-header-badpattern.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/invalid-example-header-items-default-response.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/invalid-example-header-items-response.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/invalid-example-header-items.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/invalid-example-header-pattern.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/invalid-example-header-response.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/invalid-example-header.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/invalid-example-parameter-items.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/invalid-example-parameter-ref.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/invalid-example-parameter-required.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/invalid-example-parameter-schema.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/invalid-example-parameter.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/invalid-example-response-ref.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/invalid-example-response.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/invalid-example-schema-additionalProperties.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/invalid-example-schema-allOf.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/invalid-example-schema-items-allOf.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/invalid-example-schema-items.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/invalid-example-schema-patternProperties.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/invalid-example-schema-ref.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/invalid-example-schema.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/valid-example-default-response-PatternProperties.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/valid-example-default-response.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/valid-example-header-badpattern.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/valid-example-header-items-default-response.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/valid-example-header-items-response.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/valid-example-header-items.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/valid-example-header-pattern.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/valid-example-header-response.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/valid-example-header.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/valid-example-parameter-items.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/valid-example-parameter-ref.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/valid-example-parameter-required.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/valid-example-parameter-schema.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/valid-example-parameter.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/valid-example-response-ref.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/valid-example-response.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/valid-example-schema-additionalProperties.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/valid-example-schema-allOf.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/valid-example-schema-items-allOf.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/valid-example-schema-items.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/valid-example-schema-patternProperties.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/valid-example-schema-ref.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/fixtures/validation/example/valid-example-schema.json
+pkg/mod/github.com/go-openapi/validate@v0.19.3/post/defaulter_test.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/post/defaulter.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/post/prune_test.go
+pkg/mod/github.com/go-openapi/validate@v0.19.3/post/prune.go
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/.gitignore
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/.travis.yml
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/appengine.go
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/auth_test.go
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/auth.go
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/AUTHORS
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/benchmark_go18_test.go
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/benchmark_test.go
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/buffer.go
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/CHANGELOG.md
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/collations.go
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/connection_go18_test.go
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/connection_go18.go
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/connection_test.go
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/connection.go
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/const.go
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/CONTRIBUTING.md
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/driver_go18_test.go
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/driver_test.go
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/driver.go
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/dsn_test.go
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/dsn.go
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/errors_test.go
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/errors.go
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/fields.go
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/infile.go
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/LICENSE
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/packets_test.go
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/packets.go
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/README.md
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/result.go
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/rows.go
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/statement_test.go
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/statement.go
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/transaction.go
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/utils_go17.go
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/utils_go18_test.go
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/utils_go18.go
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/utils_test.go
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/utils.go
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/.github/ISSUE_TEMPLATE.md
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/.github/PULL_REQUEST_TEMPLATE.md
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/.travis/docker.cnf
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/.travis/gofmt.sh
+pkg/mod/github.com/go-sql-driver/mysql@v1.4.1/.travis/wait_mysql.sh
+pkg/mod/github.com/go-stack/stack@v1.8.0/.travis.yml
+pkg/mod/github.com/go-stack/stack@v1.8.0/format_test.go
+pkg/mod/github.com/go-stack/stack@v1.8.0/go.mod
+pkg/mod/github.com/go-stack/stack@v1.8.0/LICENSE.md
+pkg/mod/github.com/go-stack/stack@v1.8.0/README.md
+pkg/mod/github.com/go-stack/stack@v1.8.0/stack_test.go
+pkg/mod/github.com/go-stack/stack@v1.8.0/stack-go19_test.go
+pkg/mod/github.com/go-stack/stack@v1.8.0/stack.go
+pkg/mod/github.com/golang/glog@v0.0.0-20160126235308-23def4e6c14b/glog_file.go
+pkg/mod/github.com/golang/glog@v0.0.0-20160126235308-23def4e6c14b/glog_test.go
+pkg/mod/github.com/golang/glog@v0.0.0-20160126235308-23def4e6c14b/glog.go
+pkg/mod/github.com/golang/glog@v0.0.0-20160126235308-23def4e6c14b/LICENSE
+pkg/mod/github.com/golang/glog@v0.0.0-20160126235308-23def4e6c14b/README
+pkg/mod/github.com/golang/protobuf@v1.3.3/.gitignore
+pkg/mod/github.com/golang/protobuf@v1.3.3/.travis.yml
+pkg/mod/github.com/golang/protobuf@v1.3.3/AUTHORS
+pkg/mod/github.com/golang/protobuf@v1.3.3/CONTRIBUTORS
+pkg/mod/github.com/golang/protobuf@v1.3.3/go.mod
+pkg/mod/github.com/golang/protobuf@v1.3.3/go.sum
+pkg/mod/github.com/golang/protobuf@v1.3.3/LICENSE
+pkg/mod/github.com/golang/protobuf@v1.3.3/Makefile
+pkg/mod/github.com/golang/protobuf@v1.3.3/README.md
+pkg/mod/github.com/golang/protobuf@v1.3.3/regenerate.sh
+pkg/mod/github.com/golang/protobuf@v1.3.3/.github/ISSUE_TEMPLATE/bug_report.md
+pkg/mod/github.com/golang/protobuf@v1.3.3/.github/ISSUE_TEMPLATE/feature_request.md
+pkg/mod/github.com/golang/protobuf@v1.3.3/.github/ISSUE_TEMPLATE/question.md
+pkg/mod/github.com/golang/protobuf@v1.3.3/descriptor/descriptor_test.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/descriptor/descriptor.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/jsonpb/jsonpb_test.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/jsonpb/jsonpb.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/jsonpb/jsonpb_test_proto/more_test_objects.pb.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/jsonpb/jsonpb_test_proto/more_test_objects.proto
+pkg/mod/github.com/golang/protobuf@v1.3.3/jsonpb/jsonpb_test_proto/test_objects.pb.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/jsonpb/jsonpb_test_proto/test_objects.proto
+pkg/mod/github.com/golang/protobuf@v1.3.3/proto/all_test.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/proto/any_test.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/proto/clone_test.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/proto/clone.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/proto/decode_test.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/proto/decode.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/proto/deprecated.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/proto/discard_test.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/proto/discard.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/proto/encode_test.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/proto/encode.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/proto/equal_test.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/proto/equal.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/proto/extensions_test.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/proto/extensions.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/proto/lib.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/proto/map_test.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/proto/message_set_test.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/proto/message_set.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/proto/pointer_reflect.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/proto/pointer_unsafe.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/proto/properties.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/proto/proto3_test.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/proto/size_test.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/proto/size2_test.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/proto/table_marshal.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/proto/table_merge.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/proto/table_unmarshal.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/proto/text_parser_test.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/proto/text_parser.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/proto/text_test.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/proto/text.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/proto/proto3_proto/proto3.pb.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/proto/proto3_proto/proto3.proto
+pkg/mod/github.com/golang/protobuf@v1.3.3/proto/test_proto/test.pb.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/proto/test_proto/test.proto
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/doc.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/golden_test.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/link_grpc.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/main.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/descriptor/descriptor.pb.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/descriptor/descriptor.proto
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/generator/generator.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/generator/name_test.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/generator/internal/remap/remap_test.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/generator/internal/remap/remap.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/grpc/grpc.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/plugin/plugin.pb.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/plugin/plugin.pb.golden
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/plugin/plugin.proto
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/extension_test.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/import_public_test.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/main_test.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/deprecated/deprecated.pb.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/deprecated/deprecated.proto
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/extension_base/extension_base.pb.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/extension_base/extension_base.proto
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/extension_extra/extension_extra.pb.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/extension_extra/extension_extra.proto
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/extension_user/extension_user.pb.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/extension_user/extension_user.proto
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/import_public/a.pb.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/import_public/a.proto
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/import_public/b.pb.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/import_public/b.proto
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/import_public/importing/importing.pb.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/import_public/importing/importing.proto
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/import_public/sub/a.pb.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/import_public/sub/a.proto
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/import_public/sub/b.pb.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/import_public/sub/b.proto
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/imports/test_import_a1m1.pb.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/imports/test_import_a1m1.proto
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/imports/test_import_a1m2.pb.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/imports/test_import_a1m2.proto
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/imports/test_import_all.pb.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/imports/test_import_all.proto
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/imports/fmt/m.pb.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/imports/fmt/m.proto
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/imports/test_a_1/m1.pb.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/imports/test_a_1/m1.proto
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/imports/test_a_1/m2.pb.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/imports/test_a_1/m2.proto
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/imports/test_a_2/m3.pb.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/imports/test_a_2/m3.proto
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/imports/test_a_2/m4.pb.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/imports/test_a_2/m4.proto
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/imports/test_b_1/m1.pb.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/imports/test_b_1/m1.proto
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/imports/test_b_1/m2.pb.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/imports/test_b_1/m2.proto
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/issue780_oneof_conflict/test.pb.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/issue780_oneof_conflict/test.proto
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/multi/multi1.pb.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/multi/multi1.proto
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/multi/multi2.pb.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/multi/multi2.proto
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/multi/multi3.pb.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/multi/multi3.proto
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/my_test/test.pb.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/my_test/test.proto
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/proto3/proto3.pb.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/protoc-gen-go/testdata/proto3/proto3.proto
+pkg/mod/github.com/golang/protobuf@v1.3.3/ptypes/any_test.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/ptypes/any.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/ptypes/doc.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/ptypes/duration_test.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/ptypes/duration.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/ptypes/timestamp_test.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/ptypes/timestamp.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/ptypes/any/any.pb.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/ptypes/any/any.proto
+pkg/mod/github.com/golang/protobuf@v1.3.3/ptypes/duration/duration.pb.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/ptypes/duration/duration.proto
+pkg/mod/github.com/golang/protobuf@v1.3.3/ptypes/empty/empty.pb.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/ptypes/empty/empty.proto
+pkg/mod/github.com/golang/protobuf@v1.3.3/ptypes/struct/struct.pb.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/ptypes/struct/struct.proto
+pkg/mod/github.com/golang/protobuf@v1.3.3/ptypes/timestamp/timestamp.pb.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/ptypes/timestamp/timestamp.proto
+pkg/mod/github.com/golang/protobuf@v1.3.3/ptypes/wrappers/wrappers.pb.go
+pkg/mod/github.com/golang/protobuf@v1.3.3/ptypes/wrappers/wrappers.proto
+pkg/mod/github.com/google/go-cmp@v0.4.0/.travis.yml
+pkg/mod/github.com/google/go-cmp@v0.4.0/CONTRIBUTING.md
+pkg/mod/github.com/google/go-cmp@v0.4.0/go.mod
+pkg/mod/github.com/google/go-cmp@v0.4.0/go.sum
+pkg/mod/github.com/google/go-cmp@v0.4.0/LICENSE
+pkg/mod/github.com/google/go-cmp@v0.4.0/README.md
+pkg/mod/github.com/google/go-cmp@v0.4.0/cmp/compare_test.go
+pkg/mod/github.com/google/go-cmp@v0.4.0/cmp/compare.go
+pkg/mod/github.com/google/go-cmp@v0.4.0/cmp/example_reporter_test.go
+pkg/mod/github.com/google/go-cmp@v0.4.0/cmp/example_test.go
+pkg/mod/github.com/google/go-cmp@v0.4.0/cmp/export_panic.go
+pkg/mod/github.com/google/go-cmp@v0.4.0/cmp/export_unsafe.go
+pkg/mod/github.com/google/go-cmp@v0.4.0/cmp/options_test.go
+pkg/mod/github.com/google/go-cmp@v0.4.0/cmp/options.go
+pkg/mod/github.com/google/go-cmp@v0.4.0/cmp/path.go
+pkg/mod/github.com/google/go-cmp@v0.4.0/cmp/report_compare.go
+pkg/mod/github.com/google/go-cmp@v0.4.0/cmp/report_reflect.go
+pkg/mod/github.com/google/go-cmp@v0.4.0/cmp/report_slices.go
+pkg/mod/github.com/google/go-cmp@v0.4.0/cmp/report_text.go
+pkg/mod/github.com/google/go-cmp@v0.4.0/cmp/report_value.go
+pkg/mod/github.com/google/go-cmp@v0.4.0/cmp/report.go
+pkg/mod/github.com/google/go-cmp@v0.4.0/cmp/cmpopts/equate.go
+pkg/mod/github.com/google/go-cmp@v0.4.0/cmp/cmpopts/ignore.go
+pkg/mod/github.com/google/go-cmp@v0.4.0/cmp/cmpopts/sort.go
+pkg/mod/github.com/google/go-cmp@v0.4.0/cmp/cmpopts/struct_filter.go
+pkg/mod/github.com/google/go-cmp@v0.4.0/cmp/cmpopts/util_test.go
+pkg/mod/github.com/google/go-cmp@v0.4.0/cmp/cmpopts/xform.go
+pkg/mod/github.com/google/go-cmp@v0.4.0/cmp/internal/diff/debug_disable.go
+pkg/mod/github.com/google/go-cmp@v0.4.0/cmp/internal/diff/debug_enable.go
+pkg/mod/github.com/google/go-cmp@v0.4.0/cmp/internal/diff/diff_test.go
+pkg/mod/github.com/google/go-cmp@v0.4.0/cmp/internal/diff/diff.go
+pkg/mod/github.com/google/go-cmp@v0.4.0/cmp/internal/flags/flags.go
+pkg/mod/github.com/google/go-cmp@v0.4.0/cmp/internal/flags/toolchain_legacy.go
+pkg/mod/github.com/google/go-cmp@v0.4.0/cmp/internal/flags/toolchain_recent.go
+pkg/mod/github.com/google/go-cmp@v0.4.0/cmp/internal/function/func_test.go
+pkg/mod/github.com/google/go-cmp@v0.4.0/cmp/internal/function/func.go
+pkg/mod/github.com/google/go-cmp@v0.4.0/cmp/internal/testprotos/protos.go
+pkg/mod/github.com/google/go-cmp@v0.4.0/cmp/internal/teststructs/project1.go
+pkg/mod/github.com/google/go-cmp@v0.4.0/cmp/internal/teststructs/project2.go
+pkg/mod/github.com/google/go-cmp@v0.4.0/cmp/internal/teststructs/project3.go
+pkg/mod/github.com/google/go-cmp@v0.4.0/cmp/internal/teststructs/project4.go
+pkg/mod/github.com/google/go-cmp@v0.4.0/cmp/internal/teststructs/structs.go
+pkg/mod/github.com/google/go-cmp@v0.4.0/cmp/internal/value/pointer_purego.go
+pkg/mod/github.com/google/go-cmp@v0.4.0/cmp/internal/value/pointer_unsafe.go
+pkg/mod/github.com/google/go-cmp@v0.4.0/cmp/internal/value/sort_test.go
+pkg/mod/github.com/google/go-cmp@v0.4.0/cmp/internal/value/sort.go
+pkg/mod/github.com/google/go-cmp@v0.4.0/cmp/internal/value/zero_test.go
+pkg/mod/github.com/google/go-cmp@v0.4.0/cmp/internal/value/zero.go
+pkg/mod/github.com/google/uuid@v1.1.1/.travis.yml
+pkg/mod/github.com/google/uuid@v1.1.1/CONTRIBUTING.md
+pkg/mod/github.com/google/uuid@v1.1.1/CONTRIBUTORS
+pkg/mod/github.com/google/uuid@v1.1.1/dce.go
+pkg/mod/github.com/google/uuid@v1.1.1/doc.go
+pkg/mod/github.com/google/uuid@v1.1.1/go.mod
+pkg/mod/github.com/google/uuid@v1.1.1/hash.go
+pkg/mod/github.com/google/uuid@v1.1.1/json_test.go
+pkg/mod/github.com/google/uuid@v1.1.1/LICENSE
+pkg/mod/github.com/google/uuid@v1.1.1/marshal.go
+pkg/mod/github.com/google/uuid@v1.1.1/node_js.go
+pkg/mod/github.com/google/uuid@v1.1.1/node_net.go
+pkg/mod/github.com/google/uuid@v1.1.1/node.go
+pkg/mod/github.com/google/uuid@v1.1.1/README.md
+pkg/mod/github.com/google/uuid@v1.1.1/seq_test.go
+pkg/mod/github.com/google/uuid@v1.1.1/sql_test.go
+pkg/mod/github.com/google/uuid@v1.1.1/sql.go
+pkg/mod/github.com/google/uuid@v1.1.1/time.go
+pkg/mod/github.com/google/uuid@v1.1.1/util.go
+pkg/mod/github.com/google/uuid@v1.1.1/uuid_test.go
+pkg/mod/github.com/google/uuid@v1.1.1/uuid.go
+pkg/mod/github.com/google/uuid@v1.1.1/version1.go
+pkg/mod/github.com/google/uuid@v1.1.1/version4.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/.codecov.yml
+pkg/mod/github.com/json-iterator/go@v1.1.9/.gitignore
+pkg/mod/github.com/json-iterator/go@v1.1.9/.travis.yml
+pkg/mod/github.com/json-iterator/go@v1.1.9/adapter.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/any_array.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/any_bool.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/any_float.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/any_int32.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/any_int64.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/any_invalid.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/any_nil.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/any_number.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/any_object.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/any_str.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/any_uint32.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/any_uint64.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/any.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/build.sh
+pkg/mod/github.com/json-iterator/go@v1.1.9/config.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/example_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/fuzzy_mode_convert_table.md
+pkg/mod/github.com/json-iterator/go@v1.1.9/go.mod
+pkg/mod/github.com/json-iterator/go@v1.1.9/go.sum
+pkg/mod/github.com/json-iterator/go@v1.1.9/Gopkg.lock
+pkg/mod/github.com/json-iterator/go@v1.1.9/Gopkg.toml
+pkg/mod/github.com/json-iterator/go@v1.1.9/iter_array.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/iter_float.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/iter_int.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/iter_object.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/iter_skip_sloppy_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/iter_skip_sloppy.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/iter_skip_strict.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/iter_skip.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/iter_str.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/iter.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/jsoniter.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/LICENSE
+pkg/mod/github.com/json-iterator/go@v1.1.9/pool.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/README.md
+pkg/mod/github.com/json-iterator/go@v1.1.9/reflect_array.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/reflect_dynamic.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/reflect_extension.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/reflect_json_number.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/reflect_json_raw_message.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/reflect_map.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/reflect_marshaler.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/reflect_native.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/reflect_optional.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/reflect_slice.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/reflect_struct_decoder.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/reflect_struct_encoder.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/reflect.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/stream_float.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/stream_int.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/stream_str.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/stream_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/stream.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/test.sh
+pkg/mod/github.com/json-iterator/go@v1.1.9/any_tests/jsoniter_any_array_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/any_tests/jsoniter_any_bool_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/any_tests/jsoniter_any_float_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/any_tests/jsoniter_any_int_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/any_tests/jsoniter_any_map_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/any_tests/jsoniter_any_null_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/any_tests/jsoniter_any_object_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/any_tests/jsoniter_any_string_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/any_tests/jsoniter_must_be_valid_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/any_tests/jsoniter_wrap_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/api_tests/config_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/api_tests/decoder_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/api_tests/encoder_18_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/api_tests/encoder_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/api_tests/marshal_indent_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/api_tests/marshal_json_escape_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/api_tests/marshal_json_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/benchmarks/encode_string_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/benchmarks/jsoniter_large_file_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/extension_tests/decoder_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/extension_tests/extension_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/extra/binary_as_string_codec_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/extra/binary_as_string_codec.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/extra/fuzzy_decoder_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/extra/fuzzy_decoder.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/extra/naming_strategy_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/extra/naming_strategy.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/extra/privat_fields.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/extra/private_fields_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/extra/time_as_int64_codec_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/extra/time_as_int64_codec.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/misc_tests/jsoniter_array_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/misc_tests/jsoniter_bool_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/misc_tests/jsoniter_float_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/misc_tests/jsoniter_int_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/misc_tests/jsoniter_interface_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/misc_tests/jsoniter_iterator_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/misc_tests/jsoniter_map_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/misc_tests/jsoniter_nested_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/misc_tests/jsoniter_null_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/misc_tests/jsoniter_object_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/misc_tests/jsoniter_raw_message_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/skip_tests/array_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/skip_tests/float64_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/skip_tests/jsoniter_skip_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/skip_tests/skip_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/skip_tests/string_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/skip_tests/struct_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/type_tests/array_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/type_tests/builtin_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/type_tests/map_key_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/type_tests/map_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/type_tests/marshaler_string_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/type_tests/marshaler_struct_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/type_tests/slice_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/type_tests/struct_embedded_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/type_tests/struct_field_case_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/type_tests/struct_tags_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/type_tests/struct_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/type_tests/text_marshaler_string_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/type_tests/text_marshaler_struct_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/type_tests/type_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/value_tests/array_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/value_tests/bool_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/value_tests/eface_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/value_tests/error_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/value_tests/float_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/value_tests/iface_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/value_tests/int_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/value_tests/invalid_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/value_tests/map_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/value_tests/marshaler_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/value_tests/number_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/value_tests/ptr_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/value_tests/raw_message_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/value_tests/slice_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/value_tests/string_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/value_tests/struct_test.go
+pkg/mod/github.com/json-iterator/go@v1.1.9/value_tests/value_test.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/.editorconfig
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/.gitattributes
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/.gitignore
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/.travis.yml
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/bind_test.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/bind.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/context_test.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/context.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/echo_test.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/echo.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/group_test.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/group.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/LICENSE
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/log.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/Makefile
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/README.md
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/response_test.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/response.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/router_test.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/router.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/.github/ISSUE_TEMPLATE.md
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/.github/stale.yml
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/_fixture/favicon.ico
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/_fixture/index.html
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/_fixture/certs/cert.pem
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/_fixture/certs/key.pem
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/_fixture/folder/index.html
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/_fixture/images/walle.png
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/middleware/basic_auth_test.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/middleware/basic_auth.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/middleware/body_dump_test.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/middleware/body_dump.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/middleware/body_limit_test.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/middleware/body_limit.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/middleware/compress_test.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/middleware/compress.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/middleware/cors_test.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/middleware/cors.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/middleware/csrf_test.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/middleware/csrf.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/middleware/jwt_test.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/middleware/jwt.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/middleware/key_auth_test.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/middleware/key_auth.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/middleware/logger_test.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/middleware/logger.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/middleware/method_override_test.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/middleware/method_override.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/middleware/middleware.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/middleware/proxy_1_11_n.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/middleware/proxy_1_11_test.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/middleware/proxy_1_11.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/middleware/proxy_test.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/middleware/proxy.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/middleware/recover_test.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/middleware/recover.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/middleware/redirect_test.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/middleware/redirect.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/middleware/request_id_test.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/middleware/request_id.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/middleware/rewrite_test.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/middleware/rewrite.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/middleware/secure_test.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/middleware/secure.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/middleware/slash_test.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/middleware/slash.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/middleware/static_test.go
+pkg/mod/github.com/labstack/echo@v3.3.10+incompatible/middleware/static.go
+pkg/mod/github.com/labstack/gommon@v0.3.0/.gitignore
+pkg/mod/github.com/labstack/gommon@v0.3.0/.travis.yml
+pkg/mod/github.com/labstack/gommon@v0.3.0/go.mod
+pkg/mod/github.com/labstack/gommon@v0.3.0/go.sum
+pkg/mod/github.com/labstack/gommon@v0.3.0/gommon.go
+pkg/mod/github.com/labstack/gommon@v0.3.0/LICENSE
+pkg/mod/github.com/labstack/gommon@v0.3.0/README.md
+pkg/mod/github.com/labstack/gommon@v0.3.0/bytes/bytes_test.go
+pkg/mod/github.com/labstack/gommon@v0.3.0/bytes/bytes.go
+pkg/mod/github.com/labstack/gommon@v0.3.0/bytes/README.md
+pkg/mod/github.com/labstack/gommon@v0.3.0/color/color_test.go
+pkg/mod/github.com/labstack/gommon@v0.3.0/color/color.go
+pkg/mod/github.com/labstack/gommon@v0.3.0/color/README.md
+pkg/mod/github.com/labstack/gommon@v0.3.0/email/email_test.go
+pkg/mod/github.com/labstack/gommon@v0.3.0/email/email.go
+pkg/mod/github.com/labstack/gommon@v0.3.0/log/color.go
+pkg/mod/github.com/labstack/gommon@v0.3.0/log/log_test.go
+pkg/mod/github.com/labstack/gommon@v0.3.0/log/log.go
+pkg/mod/github.com/labstack/gommon@v0.3.0/log/README.md
+pkg/mod/github.com/labstack/gommon@v0.3.0/log/white.go
+pkg/mod/github.com/labstack/gommon@v0.3.0/random/random_test.go
+pkg/mod/github.com/labstack/gommon@v0.3.0/random/random.go
+pkg/mod/github.com/lann/builder@v0.0.0-20180802200727-47ae307949d0/.gitignore
+pkg/mod/github.com/lann/builder@v0.0.0-20180802200727-47ae307949d0/.travis.yml
+pkg/mod/github.com/lann/builder@v0.0.0-20180802200727-47ae307949d0/builder_test.go
+pkg/mod/github.com/lann/builder@v0.0.0-20180802200727-47ae307949d0/builder.go
+pkg/mod/github.com/lann/builder@v0.0.0-20180802200727-47ae307949d0/example_test.go
+pkg/mod/github.com/lann/builder@v0.0.0-20180802200727-47ae307949d0/LICENSE
+pkg/mod/github.com/lann/builder@v0.0.0-20180802200727-47ae307949d0/README.md
+pkg/mod/github.com/lann/builder@v0.0.0-20180802200727-47ae307949d0/reflect.go
+pkg/mod/github.com/lann/builder@v0.0.0-20180802200727-47ae307949d0/registry.go
+pkg/mod/github.com/lann/ps@v0.0.0-20150810152359-62de8c46ede0/LICENSE
+pkg/mod/github.com/lann/ps@v0.0.0-20150810152359-62de8c46ede0/list_test.go
+pkg/mod/github.com/lann/ps@v0.0.0-20150810152359-62de8c46ede0/list.go
+pkg/mod/github.com/lann/ps@v0.0.0-20150810152359-62de8c46ede0/map_test.go
+pkg/mod/github.com/lann/ps@v0.0.0-20150810152359-62de8c46ede0/map.go
+pkg/mod/github.com/lann/ps@v0.0.0-20150810152359-62de8c46ede0/profile.sh
+pkg/mod/github.com/lann/ps@v0.0.0-20150810152359-62de8c46ede0/README.md
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/.gitignore
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/.travis.yml
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/helpers.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/LICENSE
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/Makefile
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/raw.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/README.md
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/benchmark/codec_test.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/benchmark/data_codec.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/benchmark/data_ffjson.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/benchmark/data_var.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/benchmark/data.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/benchmark/default_test.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/benchmark/dummy_test.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/benchmark/easyjson_test.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/benchmark/example.json
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/benchmark/ffjson_test.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/benchmark/jsoniter_test.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/benchmark/ujson.sh
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/bootstrap/bootstrap.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/buffer/pool_test.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/buffer/pool.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/easyjson/main.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/gen/decoder.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/gen/encoder.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/gen/generator_test.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/gen/generator.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/jlexer/bytestostr_nounsafe.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/jlexer/bytestostr.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/jlexer/error.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/jlexer/lexer_test.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/jlexer/lexer.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/jwriter/writer.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/opt/gotemplate_Bool.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/opt/gotemplate_Float32.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/opt/gotemplate_Float64.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/opt/gotemplate_Int.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/opt/gotemplate_Int8.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/opt/gotemplate_Int16.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/opt/gotemplate_Int32.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/opt/gotemplate_Int64.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/opt/gotemplate_String.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/opt/gotemplate_Uint.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/opt/gotemplate_Uint8.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/opt/gotemplate_Uint16.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/opt/gotemplate_Uint32.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/opt/gotemplate_Uint64.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/opt/opts.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/opt/optional/opt.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/parser/parser.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/parser/pkgpath.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/tests/basic_test.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/tests/custom_map_key_type.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/tests/data.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/tests/disallow_unknown.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/tests/embedded_type.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/tests/errors_test.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/tests/errors.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/tests/key_marshaler_map.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/tests/named_type.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/tests/nested_easy.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/tests/nothing.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/tests/omitempty.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/tests/opt_test.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/tests/reference_to_pointer.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/tests/required_test.go
+pkg/mod/github.com/mailru/easyjson@v0.0.0-20190626092158-b2ccc519800e/tests/snake.go
+pkg/mod/github.com/mattn/go-colorable@v0.1.2/.travis.yml
+pkg/mod/github.com/mattn/go-colorable@v0.1.2/colorable_appengine.go
+pkg/mod/github.com/mattn/go-colorable@v0.1.2/colorable_others.go
+pkg/mod/github.com/mattn/go-colorable@v0.1.2/colorable_test.go
+pkg/mod/github.com/mattn/go-colorable@v0.1.2/colorable_windows.go
+pkg/mod/github.com/mattn/go-colorable@v0.1.2/go.mod
+pkg/mod/github.com/mattn/go-colorable@v0.1.2/go.sum
+pkg/mod/github.com/mattn/go-colorable@v0.1.2/LICENSE
+pkg/mod/github.com/mattn/go-colorable@v0.1.2/noncolorable.go
+pkg/mod/github.com/mattn/go-colorable@v0.1.2/README.md
+pkg/mod/github.com/mattn/go-colorable@v0.1.2/_example/escape-seq/main.go
+pkg/mod/github.com/mattn/go-colorable@v0.1.2/_example/logrus/main.go
+pkg/mod/github.com/mattn/go-colorable@v0.1.2/_example/title/main.go
+pkg/mod/github.com/mattn/go-colorable@v0.1.2/cmd/colorable/colorable.go
+pkg/mod/github.com/mattn/go-isatty@v0.0.9/.travis.yml
+pkg/mod/github.com/mattn/go-isatty@v0.0.9/doc.go
+pkg/mod/github.com/mattn/go-isatty@v0.0.9/example_test.go
+pkg/mod/github.com/mattn/go-isatty@v0.0.9/go.mod
+pkg/mod/github.com/mattn/go-isatty@v0.0.9/go.sum
+pkg/mod/github.com/mattn/go-isatty@v0.0.9/isatty_android.go
+pkg/mod/github.com/mattn/go-isatty@v0.0.9/isatty_bsd.go
+pkg/mod/github.com/mattn/go-isatty@v0.0.9/isatty_others_test.go
+pkg/mod/github.com/mattn/go-isatty@v0.0.9/isatty_others.go
+pkg/mod/github.com/mattn/go-isatty@v0.0.9/isatty_solaris.go
+pkg/mod/github.com/mattn/go-isatty@v0.0.9/isatty_tcgets.go
+pkg/mod/github.com/mattn/go-isatty@v0.0.9/isatty_windows_test.go
+pkg/mod/github.com/mattn/go-isatty@v0.0.9/isatty_windows.go
+pkg/mod/github.com/mattn/go-isatty@v0.0.9/LICENSE
+pkg/mod/github.com/mattn/go-isatty@v0.0.9/README.md
+pkg/mod/github.com/mattn/go-isatty@v0.0.9/.github/FUNDING.yml
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/.gitignore
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/.travis.yml
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/backup_test.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/backup.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/callback_test.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/callback.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/doc.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/error_test.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/error.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/LICENSE
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/README.md
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/sqlite3_context.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/sqlite3_func_crypt_test.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/sqlite3_func_crypt.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/sqlite3_go18_test.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/sqlite3_go18.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/sqlite3_libsqlite3.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/sqlite3_load_extension_omit.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/sqlite3_load_extension.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/sqlite3_opt_allow_uri_authority.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/sqlite3_opt_app_armor.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/sqlite3_opt_foreign_keys.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/sqlite3_opt_fts3_test.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/sqlite3_opt_fts5.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/sqlite3_opt_icu.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/sqlite3_opt_introspect.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/sqlite3_opt_json1.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/sqlite3_opt_secure_delete_fast.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/sqlite3_opt_secure_delete.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/sqlite3_opt_stat4.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/sqlite3_opt_unlock_notify_test.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/sqlite3_opt_unlock_notify.c
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/sqlite3_opt_unlock_notify.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/sqlite3_opt_userauth_omit.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/sqlite3_opt_userauth_test.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/sqlite3_opt_userauth.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/sqlite3_opt_vacuum_full.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/sqlite3_opt_vacuum_incr.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/sqlite3_opt_vtable_test.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/sqlite3_opt_vtable.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/sqlite3_other.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/sqlite3_solaris.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/sqlite3_test.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/sqlite3_trace.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/sqlite3_type.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/sqlite3_usleep_windows.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/sqlite3_windows.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/sqlite3-binding.c
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/sqlite3-binding.h
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/sqlite3.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/sqlite3ext.h
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/static_mock.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/.github/FUNDING.yml
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/_example/custom_func/main.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/_example/hook/hook.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/_example/limit/limit.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/_example/mod_regexp/extension.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/_example/mod_regexp/Makefile
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/_example/mod_regexp/sqlite3_mod_regexp.c
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/_example/mod_vtable/extension.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/_example/mod_vtable/Makefile
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/_example/mod_vtable/picojson.h
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/_example/mod_vtable/sqlite3_mod_vtable.cc
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/_example/simple/simple.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/_example/trace/main.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/_example/vtable/main.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/_example/vtable/vtable.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/upgrade/package.go
+pkg/mod/github.com/mattn/go-sqlite3@v1.11.0/upgrade/upgrade.go
+pkg/mod/github.com/matttproud/golang_protobuf_extensions@v1.0.1/.travis.yml
+pkg/mod/github.com/matttproud/golang_protobuf_extensions@v1.0.1/LICENSE
+pkg/mod/github.com/matttproud/golang_protobuf_extensions@v1.0.1/Makefile.TRAVIS
+pkg/mod/github.com/matttproud/golang_protobuf_extensions@v1.0.1/NOTICE
+pkg/mod/github.com/matttproud/golang_protobuf_extensions@v1.0.1/README.md
+pkg/mod/github.com/matttproud/golang_protobuf_extensions@v1.0.1/ext/moved.go
+pkg/mod/github.com/matttproud/golang_protobuf_extensions@v1.0.1/pbtest/deleted.go
+pkg/mod/github.com/matttproud/golang_protobuf_extensions@v1.0.1/pbutil/.gitignore
+pkg/mod/github.com/matttproud/golang_protobuf_extensions@v1.0.1/pbutil/all_test.go
+pkg/mod/github.com/matttproud/golang_protobuf_extensions@v1.0.1/pbutil/decode_test.go
+pkg/mod/github.com/matttproud/golang_protobuf_extensions@v1.0.1/pbutil/decode.go
+pkg/mod/github.com/matttproud/golang_protobuf_extensions@v1.0.1/pbutil/doc.go
+pkg/mod/github.com/matttproud/golang_protobuf_extensions@v1.0.1/pbutil/encode_test.go
+pkg/mod/github.com/matttproud/golang_protobuf_extensions@v1.0.1/pbutil/encode.go
+pkg/mod/github.com/matttproud/golang_protobuf_extensions@v1.0.1/pbutil/Makefile
+pkg/mod/github.com/matttproud/golang_protobuf_extensions@v1.0.1/testdata/README.THIRD_PARTY
+pkg/mod/github.com/matttproud/golang_protobuf_extensions@v1.0.1/testdata/test.pb.go
+pkg/mod/github.com/matttproud/golang_protobuf_extensions@v1.0.1/testdata/test.proto
+pkg/mod/github.com/mitchellh/mapstructure@v1.3.2/.travis.yml
+pkg/mod/github.com/mitchellh/mapstructure@v1.3.2/CHANGELOG.md
+pkg/mod/github.com/mitchellh/mapstructure@v1.3.2/decode_hooks_test.go
+pkg/mod/github.com/mitchellh/mapstructure@v1.3.2/decode_hooks.go
+pkg/mod/github.com/mitchellh/mapstructure@v1.3.2/error.go
+pkg/mod/github.com/mitchellh/mapstructure@v1.3.2/go.mod
+pkg/mod/github.com/mitchellh/mapstructure@v1.3.2/LICENSE
+pkg/mod/github.com/mitchellh/mapstructure@v1.3.2/mapstructure_benchmark_test.go
+pkg/mod/github.com/mitchellh/mapstructure@v1.3.2/mapstructure_bugs_test.go
+pkg/mod/github.com/mitchellh/mapstructure@v1.3.2/mapstructure_examples_test.go
+pkg/mod/github.com/mitchellh/mapstructure@v1.3.2/mapstructure_test.go
+pkg/mod/github.com/mitchellh/mapstructure@v1.3.2/mapstructure.go
+pkg/mod/github.com/mitchellh/mapstructure@v1.3.2/README.md
+pkg/mod/github.com/modern-go/concurrent@v0.0.0-20180306012644-bacd9c7ef1dd/.gitignore
+pkg/mod/github.com/modern-go/concurrent@v0.0.0-20180306012644-bacd9c7ef1dd/.travis.yml
+pkg/mod/github.com/modern-go/concurrent@v0.0.0-20180306012644-bacd9c7ef1dd/executor.go
+pkg/mod/github.com/modern-go/concurrent@v0.0.0-20180306012644-bacd9c7ef1dd/go_above_19.go
+pkg/mod/github.com/modern-go/concurrent@v0.0.0-20180306012644-bacd9c7ef1dd/go_below_19.go
+pkg/mod/github.com/modern-go/concurrent@v0.0.0-20180306012644-bacd9c7ef1dd/LICENSE
+pkg/mod/github.com/modern-go/concurrent@v0.0.0-20180306012644-bacd9c7ef1dd/log.go
+pkg/mod/github.com/modern-go/concurrent@v0.0.0-20180306012644-bacd9c7ef1dd/map_test.go
+pkg/mod/github.com/modern-go/concurrent@v0.0.0-20180306012644-bacd9c7ef1dd/README.md
+pkg/mod/github.com/modern-go/concurrent@v0.0.0-20180306012644-bacd9c7ef1dd/test.sh
+pkg/mod/github.com/modern-go/concurrent@v0.0.0-20180306012644-bacd9c7ef1dd/unbounded_executor_test.go
+pkg/mod/github.com/modern-go/concurrent@v0.0.0-20180306012644-bacd9c7ef1dd/unbounded_executor.go
+pkg/mod/github.com/modern-go/reflect2@v1.0.1/.gitignore
+pkg/mod/github.com/modern-go/reflect2@v1.0.1/.travis.yml
+pkg/mod/github.com/modern-go/reflect2@v1.0.1/go_above_17.go
+pkg/mod/github.com/modern-go/reflect2@v1.0.1/go_above_19.go
+pkg/mod/github.com/modern-go/reflect2@v1.0.1/go_below_17.go
+pkg/mod/github.com/modern-go/reflect2@v1.0.1/go_below_19.go
+pkg/mod/github.com/modern-go/reflect2@v1.0.1/Gopkg.lock
+pkg/mod/github.com/modern-go/reflect2@v1.0.1/Gopkg.toml
+pkg/mod/github.com/modern-go/reflect2@v1.0.1/LICENSE
+pkg/mod/github.com/modern-go/reflect2@v1.0.1/README.md
+pkg/mod/github.com/modern-go/reflect2@v1.0.1/reflect2_amd64.s
+pkg/mod/github.com/modern-go/reflect2@v1.0.1/reflect2_kind.go
+pkg/mod/github.com/modern-go/reflect2@v1.0.1/reflect2.go
+pkg/mod/github.com/modern-go/reflect2@v1.0.1/relfect2_386.s
+pkg/mod/github.com/modern-go/reflect2@v1.0.1/relfect2_amd64p32.s
+pkg/mod/github.com/modern-go/reflect2@v1.0.1/relfect2_arm.s
+pkg/mod/github.com/modern-go/reflect2@v1.0.1/relfect2_arm64.s
+pkg/mod/github.com/modern-go/reflect2@v1.0.1/relfect2_mips64x.s
+pkg/mod/github.com/modern-go/reflect2@v1.0.1/relfect2_mipsx.s
+pkg/mod/github.com/modern-go/reflect2@v1.0.1/relfect2_ppc64x.s
+pkg/mod/github.com/modern-go/reflect2@v1.0.1/relfect2_s390x.s
+pkg/mod/github.com/modern-go/reflect2@v1.0.1/safe_field.go
+pkg/mod/github.com/modern-go/reflect2@v1.0.1/safe_map.go
+pkg/mod/github.com/modern-go/reflect2@v1.0.1/safe_slice.go
+pkg/mod/github.com/modern-go/reflect2@v1.0.1/safe_struct.go
+pkg/mod/github.com/modern-go/reflect2@v1.0.1/safe_type.go
+pkg/mod/github.com/modern-go/reflect2@v1.0.1/test.sh
+pkg/mod/github.com/modern-go/reflect2@v1.0.1/type_map.go
+pkg/mod/github.com/modern-go/reflect2@v1.0.1/unsafe_array.go
+pkg/mod/github.com/modern-go/reflect2@v1.0.1/unsafe_eface.go
+pkg/mod/github.com/modern-go/reflect2@v1.0.1/unsafe_field.go
+pkg/mod/github.com/modern-go/reflect2@v1.0.1/unsafe_iface.go
+pkg/mod/github.com/modern-go/reflect2@v1.0.1/unsafe_link.go
+pkg/mod/github.com/modern-go/reflect2@v1.0.1/unsafe_map.go
+pkg/mod/github.com/modern-go/reflect2@v1.0.1/unsafe_ptr.go
+pkg/mod/github.com/modern-go/reflect2@v1.0.1/unsafe_slice.go
+pkg/mod/github.com/modern-go/reflect2@v1.0.1/unsafe_struct.go
+pkg/mod/github.com/modern-go/reflect2@v1.0.1/unsafe_type.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/.fossa.yml
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/.gitignore
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/.golangci.yml
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/.travis.yml
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/acknowledged_response.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/backoff_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/backoff.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/bulk_delete_request_easyjson.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/bulk_delete_request_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/bulk_delete_request.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/bulk_index_request_easyjson.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/bulk_index_request_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/bulk_index_request.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/bulk_processor_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/bulk_processor.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/bulk_request.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/bulk_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/bulk_update_request_easyjson.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/bulk_update_request_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/bulk_update_request.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/bulk.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/canonicalize_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/canonicalize.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/cat_aliases_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/cat_aliases.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/cat_allocation_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/cat_allocation.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/cat_count_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/cat_count.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/cat_health_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/cat_health.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/cat_indices_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/cat_indices.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/CHANGELOG-3.0.md
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/CHANGELOG-5.0.md
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/CHANGELOG-6.0.md
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/CHANGELOG-7.0.md
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/clear_scroll_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/clear_scroll.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/client_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/client.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/cluster_health_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/cluster_health.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/cluster_reroute_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/cluster_reroute.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/cluster_state_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/cluster_state.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/cluster_stats_integration_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/cluster_stats_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/cluster_stats.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/CODE_OF_CONDUCT.md
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/connection.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/CONTRIBUTING.md
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/CONTRIBUTORS
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/count_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/count.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/decoder_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/decoder.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/delete_by_query_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/delete_by_query.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/delete_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/delete.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/doc.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/docker-compose.yml
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/docvalue_field_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/docvalue_field.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/errors_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/errors.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/example_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/exists_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/exists.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/explain_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/explain.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/fetch_source_context_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/fetch_source_context.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/field_caps_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/field_caps.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/geo_point_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/geo_point.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/get_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/get.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/go.mod
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/highlight_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/highlight.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/index_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/index.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_analyze_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_analyze.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_close_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_close.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_create_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_create.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_delete_template.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_delete_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_delete.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_exists_template_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_exists_template.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_exists_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_exists.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_flush_synced_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_flush_synced.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_flush_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_flush.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_forcemerge_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_forcemerge.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_freeze_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_freeze.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_get_aliases_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_get_aliases.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_get_field_mapping_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_get_field_mapping.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_get_mapping_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_get_mapping.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_get_settings_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_get_settings.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_get_template_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_get_template.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_get_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_get.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_open_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_open.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_put_alias_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_put_alias.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_put_mapping_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_put_mapping.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_put_settings_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_put_settings.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_put_template.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_refresh_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_refresh.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_rollover_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_rollover.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_segments_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_segments.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_shrink_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_shrink.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_stats_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_stats.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_unfreeze_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/indices_unfreeze.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/ingest_delete_pipeline_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/ingest_delete_pipeline.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/ingest_get_pipeline_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/ingest_get_pipeline.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/ingest_put_pipeline_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/ingest_put_pipeline.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/ingest_simulate_pipeline_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/ingest_simulate_pipeline.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/inner_hit_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/inner_hit.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/ISSUE_TEMPLATE.md
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/LICENSE
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/logger.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/mget_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/mget.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/msearch_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/msearch.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/mtermvectors_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/mtermvectors.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/nodes_info_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/nodes_info.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/nodes_stats_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/nodes_stats.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/percolate_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/ping_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/ping.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/plugins_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/plugins.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/query.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/README.md
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/reindex_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/reindex.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/request_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/request.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/rescore.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/rescorer.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/response_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/response.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/retrier_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/retrier.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/retry_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/retry.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/run-es.sh
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/run-tests.sh
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/script_delete_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/script_delete.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/script_get_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/script_get.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/script_put_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/script_put.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/script_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/script.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/scroll_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/scroll.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_adjacency_matrix_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_adjacency_matrix.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_auto_date_histogram_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_auto_date_histogram.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_children_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_children.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_composite_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_composite.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_count_thresholds.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_date_histogram_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_date_histogram.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_date_range_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_date_range.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_diversified_sampler_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_diversified_sampler.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_filter_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_filter.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_filters_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_filters.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_geo_distance_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_geo_distance.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_geohash_grid_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_geohash_grid.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_global_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_global.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_histogram_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_histogram.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_ip_range_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_ip_range.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_missing_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_missing.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_nested_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_nested.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_range_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_range.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_reverse_nested_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_reverse_nested.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_sampler_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_sampler.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_significant_terms_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_significant_terms.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_significant_text_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_significant_text.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_terms_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_bucket_terms.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_matrix_stats_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_matrix_stats.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_metrics_avg_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_metrics_avg.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_metrics_cardinality_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_metrics_cardinality.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_metrics_extended_stats_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_metrics_extended_stats.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_metrics_geo_bounds_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_metrics_geo_bounds.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_metrics_geo_centroid_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_metrics_geo_centroid.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_metrics_max_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_metrics_max.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_metrics_min_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_metrics_min.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_metrics_percentile_ranks_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_metrics_percentile_ranks.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_metrics_percentiles_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_metrics_percentiles.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_metrics_scripted_metric_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_metrics_scripted_metric.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_metrics_stats_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_metrics_stats.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_metrics_sum_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_metrics_sum.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_metrics_top_hits_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_metrics_top_hits.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_metrics_value_count_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_metrics_value_count.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_metrics_weighted_avg_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_metrics_weighted_avg.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_pipeline_avg_bucket_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_pipeline_avg_bucket.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_pipeline_bucket_script_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_pipeline_bucket_script.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_pipeline_bucket_selector_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_pipeline_bucket_selector.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_pipeline_bucket_sort_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_pipeline_bucket_sort.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_pipeline_cumulative_sum_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_pipeline_cumulative_sum.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_pipeline_derivative_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_pipeline_derivative.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_pipeline_extended_stats_bucket_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_pipeline_extended_stats_bucket.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_pipeline_max_bucket_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_pipeline_max_bucket.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_pipeline_min_bucket_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_pipeline_min_bucket.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_pipeline_mov_avg_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_pipeline_mov_avg.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_pipeline_mov_fn_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_pipeline_mov_fn.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_pipeline_percentiles_bucket_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_pipeline_percentiles_bucket.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_pipeline_serial_diff_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_pipeline_serial_diff.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_pipeline_stats_bucket_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_pipeline_stats_bucket.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_pipeline_sum_bucket_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_pipeline_sum_bucket.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_pipeline_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_aggs.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_collapse_builder_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_collapse_builder.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_bool_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_bool.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_boosting_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_boosting.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_common_terms_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_common_terms.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_constant_score_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_constant_score.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_dis_max_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_dis_max.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_exists_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_exists.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_fsq_score_funcs.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_fsq_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_fsq.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_fuzzy_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_fuzzy.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_geo_bounding_box_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_geo_bounding_box.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_geo_distance_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_geo_distance.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_geo_polygon_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_geo_polygon.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_has_child_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_has_child.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_has_parent_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_has_parent.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_ids_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_ids.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_match_all_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_match_all.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_match_none_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_match_none.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_match_phrase_prefix_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_match_phrase_prefix.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_match_phrase_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_match_phrase.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_match_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_match.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_more_like_this_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_more_like_this.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_multi_match_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_multi_match.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_nested_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_nested.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_parent_id_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_parent_id.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_percolator_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_percolator.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_prefix_example_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_prefix_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_prefix.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_query_string_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_query_string.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_range_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_range.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_raw_string_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_raw_string.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_regexp_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_regexp.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_script_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_script.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_simple_query_string_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_simple_query_string.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_slice_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_slice.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_term_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_term.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_terms_set_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_terms_set.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_terms_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_terms.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_type_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_type.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_wildcard_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_wildcard.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_wrapper_integration_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_wrapper_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_queries_wrapper.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_request_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_request.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_shards_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_shards.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_source_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_source.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_suggester_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_terms_lookup_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_terms_lookup.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/search.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/setup_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/snapshot_create_repository_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/snapshot_create_repository.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/snapshot_create_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/snapshot_create.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/snapshot_delete_repository_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/snapshot_delete_repository.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/snapshot_delete_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/snapshot_delete.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/snapshot_get_repository_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/snapshot_get_repository.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/snapshot_get_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/snapshot_get.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/snapshot_restore_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/snapshot_restore.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/snapshot_verify_repository_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/snapshot_verify_repository.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/sort_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/sort.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/suggest_field_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/suggest_field.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/suggester_completion_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/suggester_completion.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/suggester_context_category_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/suggester_context_category.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/suggester_context_geo_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/suggester_context_geo.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/suggester_context_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/suggester_context.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/suggester_phrase_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/suggester_phrase.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/suggester_term_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/suggester_term.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/suggester.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/tasks_cancel_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/tasks_cancel.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/tasks_get_task_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/tasks_get_task.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/tasks_list_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/tasks_list.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/termvectors_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/termvectors.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/update_by_query_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/update_by_query.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/update_integration_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/update_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/update.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/validate_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/validate.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/xpack_ilm_delete_lifecycle.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/xpack_ilm_get_lifecycle.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/xpack_ilm_put_lifecycle.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/xpack_ilm_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/xpack_info_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/xpack_info.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/xpack_security_change_password_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/xpack_security_change_password.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/xpack_security_delete_role_mapping_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/xpack_security_delete_role_mapping.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/xpack_security_delete_role_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/xpack_security_delete_role.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/xpack_security_get_role_mapping_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/xpack_security_get_role_mapping.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/xpack_security_get_role_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/xpack_security_get_role.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/xpack_security_put_role_mapping_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/xpack_security_put_role_mapping.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/xpack_security_put_role_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/xpack_security_put_role.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/xpack_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/xpack_watcher_ack_watch_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/xpack_watcher_ack_watch.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/xpack_watcher_activate_watch_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/xpack_watcher_activate_watch.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/xpack_watcher_deactivate_watch_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/xpack_watcher_deactivate_watch.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/xpack_watcher_delete_watch_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/xpack_watcher_delete_watch.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/xpack_watcher_execute_watch_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/xpack_watcher_execute_watch.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/xpack_watcher_get_watch_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/xpack_watcher_get_watch.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/xpack_watcher_put_watch_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/xpack_watcher_put_watch.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/xpack_watcher_start_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/xpack_watcher_start.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/xpack_watcher_stats_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/xpack_watcher_stats.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/xpack_watcher_stop_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/xpack_watcher_stop.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/aws/sign_v4_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/aws/sign_v4.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/aws/v4/aws_v4_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/aws/v4/aws_v4.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/aws/v4/CREDITS
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/cluster-test/cluster-test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/cluster-test/Makefile
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/cluster-test/README.md
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/config/config_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/config/config.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/config/doc.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/etc/elasticsearch.yml
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/etc/jvm.options
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/etc/log4j2.properties
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/etc/ingest-geoip/.gitkeep
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/etc/scripts/.gitkeep
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/recipes/aws-connect/.gitignore
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/recipes/aws-connect/main.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/recipes/aws-connect-v4/.gitignore
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/recipes/aws-connect-v4/main.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/recipes/aws-mapping-v4/.gitignore
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/recipes/aws-mapping-v4/main.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/recipes/bulk_insert/.gitignore
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/recipes/bulk_insert/bulk_insert.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/recipes/bulk_processor/.gitignore
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/recipes/bulk_processor/main.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/recipes/connect/.gitignore
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/recipes/connect/connect.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/recipes/connect_with_config/.gitignore
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/recipes/connect_with_config/connect_with_config.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/recipes/go-modules/.gitignore
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/recipes/go-modules/main.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/recipes/mapping/.gitignore
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/recipes/mapping/mapping.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/recipes/middleware/.gitignore
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/recipes/middleware/main.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/recipes/scroll/.gitignore
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/recipes/scroll/scroll.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/recipes/sliced_scroll/.gitignore
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/recipes/sliced_scroll/sliced_scroll.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/recipes/suggesters/completion/.gitignore
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/recipes/suggesters/completion/main.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/recipes/text_vs_keyword/main.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/recipes/tracing/.gitignore
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/recipes/tracing/README.md
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/recipes/tracing/run-tracer.sh
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/recipes/tracing/tracing.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/trace/opencensus/transport_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/trace/opencensus/transport.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/trace/opencensus/util.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/trace/opentracing/transport_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/trace/opentracing/transport.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/trace/opentracing/util.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/uritemplates/LICENSE
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/uritemplates/uritemplates.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/uritemplates/utils_test.go
+pkg/mod/github.com/olivere/elastic/v7@v7.0.6/uritemplates/utils.go
+pkg/mod/github.com/pkg/errors@v0.8.1/.gitignore
+pkg/mod/github.com/pkg/errors@v0.8.1/.travis.yml
+pkg/mod/github.com/pkg/errors@v0.8.1/appveyor.yml
+pkg/mod/github.com/pkg/errors@v0.8.1/bench_test.go
+pkg/mod/github.com/pkg/errors@v0.8.1/errors_test.go
+pkg/mod/github.com/pkg/errors@v0.8.1/errors.go
+pkg/mod/github.com/pkg/errors@v0.8.1/example_test.go
+pkg/mod/github.com/pkg/errors@v0.8.1/format_test.go
+pkg/mod/github.com/pkg/errors@v0.8.1/LICENSE
+pkg/mod/github.com/pkg/errors@v0.8.1/README.md
+pkg/mod/github.com/pkg/errors@v0.8.1/stack_test.go
+pkg/mod/github.com/pkg/errors@v0.8.1/stack.go
+pkg/mod/github.com/pmezard/go-difflib@v1.0.0/.travis.yml
+pkg/mod/github.com/pmezard/go-difflib@v1.0.0/LICENSE
+pkg/mod/github.com/pmezard/go-difflib@v1.0.0/README.md
+pkg/mod/github.com/pmezard/go-difflib@v1.0.0/difflib/difflib_test.go
+pkg/mod/github.com/pmezard/go-difflib@v1.0.0/difflib/difflib.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/.gitignore
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/.golangci.yml
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/.travis.yml
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/CHANGELOG.md
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/CONTRIBUTING.md
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/Dockerfile
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/go.mod
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/go.sum
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/LICENSE
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/MAINTAINERS.md
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/Makefile
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/Makefile.common
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/NOTICE
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/README.md
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/VERSION
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/.circleci/config.yml
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/.github/ISSUE_TEMPLATE.md
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/api/client_test.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/api/client.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/api/prometheus/v1/api_bench_test.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/api/prometheus/v1/api_test.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/api/prometheus/v1/api.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/api/prometheus/v1/example_test.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/examples/random/main.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/examples/simple/main.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/.gitignore
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/benchmark_test.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/build_info_pre_1.12.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/build_info.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/collector_test.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/collector.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/counter_test.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/counter.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/desc_test.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/desc.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/doc.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/example_clustermanager_test.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/example_timer_complex_test.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/example_timer_gauge_test.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/example_timer_test.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/examples_test.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/expvar_collector_test.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/expvar_collector.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/fnv.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/gauge_test.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/gauge.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/go_collector_test.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/go_collector.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/histogram_test.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/histogram.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/labels.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/metric_test.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/metric.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/observer.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/process_collector_other.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/process_collector_test.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/process_collector_windows_test.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/process_collector_windows.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/process_collector.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/README.md
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/registry_test.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/registry.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/summary_test.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/summary.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/timer_test.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/timer.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/untyped.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/value_test.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/value.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/vec_test.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/vec.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/wrap_test.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/wrap.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/graphite/bridge_test.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/graphite/bridge.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/internal/metric.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/promauto/auto.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/promhttp/delegator.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/promhttp/http_test.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/promhttp/http.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/promhttp/instrument_client_test.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/promhttp/instrument_client.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/promhttp/instrument_server_test.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/promhttp/instrument_server.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/push/example_add_from_gatherer_test.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/push/examples_test.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/push/push_test.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/push/push.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/testutil/testutil_test.go
+pkg/mod/github.com/prometheus/client_golang@v1.5.1/prometheus/testutil/testutil.go
+pkg/mod/github.com/prometheus/client_model@v0.2.0/.gitignore
+pkg/mod/github.com/prometheus/client_model@v0.2.0/CONTRIBUTING.md
+pkg/mod/github.com/prometheus/client_model@v0.2.0/go.mod
+pkg/mod/github.com/prometheus/client_model@v0.2.0/go.sum
+pkg/mod/github.com/prometheus/client_model@v0.2.0/LICENSE
+pkg/mod/github.com/prometheus/client_model@v0.2.0/MAINTAINERS.md
+pkg/mod/github.com/prometheus/client_model@v0.2.0/Makefile
+pkg/mod/github.com/prometheus/client_model@v0.2.0/metrics.proto
+pkg/mod/github.com/prometheus/client_model@v0.2.0/NOTICE
+pkg/mod/github.com/prometheus/client_model@v0.2.0/README.md
+pkg/mod/github.com/prometheus/client_model@v0.2.0/go/metrics.pb.go
+pkg/mod/github.com/prometheus/common@v0.9.1/.gitignore
+pkg/mod/github.com/prometheus/common@v0.9.1/.travis.yml
+pkg/mod/github.com/prometheus/common@v0.9.1/CONTRIBUTING.md
+pkg/mod/github.com/prometheus/common@v0.9.1/go.mod
+pkg/mod/github.com/prometheus/common@v0.9.1/go.sum
+pkg/mod/github.com/prometheus/common@v0.9.1/LICENSE
+pkg/mod/github.com/prometheus/common@v0.9.1/MAINTAINERS.md
+pkg/mod/github.com/prometheus/common@v0.9.1/Makefile
+pkg/mod/github.com/prometheus/common@v0.9.1/Makefile.common
+pkg/mod/github.com/prometheus/common@v0.9.1/NOTICE
+pkg/mod/github.com/prometheus/common@v0.9.1/README.md
+pkg/mod/github.com/prometheus/common@v0.9.1/config/config.go
+pkg/mod/github.com/prometheus/common@v0.9.1/config/http_config_test.go
+pkg/mod/github.com/prometheus/common@v0.9.1/config/http_config.go
+pkg/mod/github.com/prometheus/common@v0.9.1/config/tls_config_test.go
+pkg/mod/github.com/prometheus/common@v0.9.1/config/testdata/basic-auth-password
+pkg/mod/github.com/prometheus/common@v0.9.1/config/testdata/bearer.token
+pkg/mod/github.com/prometheus/common@v0.9.1/config/testdata/client-no-pass.key
+pkg/mod/github.com/prometheus/common@v0.9.1/config/testdata/client.crt
+pkg/mod/github.com/prometheus/common@v0.9.1/config/testdata/empty
+pkg/mod/github.com/prometheus/common@v0.9.1/config/testdata/http.conf.basic-auth.good.yaml
+pkg/mod/github.com/prometheus/common@v0.9.1/config/testdata/http.conf.basic-auth.no-password.yaml
+pkg/mod/github.com/prometheus/common@v0.9.1/config/testdata/http.conf.basic-auth.no-username.yaml
+pkg/mod/github.com/prometheus/common@v0.9.1/config/testdata/http.conf.basic-auth.too-much.bad.yaml
+pkg/mod/github.com/prometheus/common@v0.9.1/config/testdata/http.conf.bearer-token-and-file-set.bad.yml
+pkg/mod/github.com/prometheus/common@v0.9.1/config/testdata/http.conf.empty.bad.yml
+pkg/mod/github.com/prometheus/common@v0.9.1/config/testdata/http.conf.good.yml
+pkg/mod/github.com/prometheus/common@v0.9.1/config/testdata/http.conf.invalid-bearer-token-file.bad.yml
+pkg/mod/github.com/prometheus/common@v0.9.1/config/testdata/self-signed-client.crt
+pkg/mod/github.com/prometheus/common@v0.9.1/config/testdata/self-signed-client.key
+pkg/mod/github.com/prometheus/common@v0.9.1/config/testdata/server.crt
+pkg/mod/github.com/prometheus/common@v0.9.1/config/testdata/server.key
+pkg/mod/github.com/prometheus/common@v0.9.1/config/testdata/tls_config.cert_no_key.bad.yml
+pkg/mod/github.com/prometheus/common@v0.9.1/config/testdata/tls_config.empty.good.yml
+pkg/mod/github.com/prometheus/common@v0.9.1/config/testdata/tls_config.insecure.good.yml
+pkg/mod/github.com/prometheus/common@v0.9.1/config/testdata/tls_config.invalid_field.bad.yml
+pkg/mod/github.com/prometheus/common@v0.9.1/config/testdata/tls_config.key_no_cert.bad.yml
+pkg/mod/github.com/prometheus/common@v0.9.1/config/testdata/tls-ca-chain.pem
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/bench_test.go
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/decode_test.go
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/decode.go
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/encode_test.go
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/encode.go
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/expfmt.go
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/fuzz.go
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/openmetrics_create_test.go
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/openmetrics_create.go
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/text_create_test.go
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/text_create.go
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/text_parse_test.go
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/text_parse.go
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/fuzz/corpus/from_test_parse_0
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/fuzz/corpus/from_test_parse_1
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/fuzz/corpus/from_test_parse_2
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/fuzz/corpus/from_test_parse_3
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/fuzz/corpus/from_test_parse_4
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/fuzz/corpus/from_test_parse_error_0
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/fuzz/corpus/from_test_parse_error_1
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/fuzz/corpus/from_test_parse_error_2
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/fuzz/corpus/from_test_parse_error_3
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/fuzz/corpus/from_test_parse_error_4
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/fuzz/corpus/from_test_parse_error_5
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/fuzz/corpus/from_test_parse_error_6
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/fuzz/corpus/from_test_parse_error_7
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/fuzz/corpus/from_test_parse_error_8
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/fuzz/corpus/from_test_parse_error_9
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/fuzz/corpus/from_test_parse_error_10
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/fuzz/corpus/from_test_parse_error_11
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/fuzz/corpus/from_test_parse_error_12
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/fuzz/corpus/from_test_parse_error_13
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/fuzz/corpus/from_test_parse_error_14
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/fuzz/corpus/from_test_parse_error_15
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/fuzz/corpus/from_test_parse_error_16
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/fuzz/corpus/from_test_parse_error_17
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/fuzz/corpus/from_test_parse_error_18
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/fuzz/corpus/from_test_parse_error_19
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/fuzz/corpus/minimal
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/testdata/json2
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/testdata/json2_bad
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/testdata/protobuf
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/testdata/protobuf.gz
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/testdata/text
+pkg/mod/github.com/prometheus/common@v0.9.1/expfmt/testdata/text.gz
+pkg/mod/github.com/prometheus/common@v0.9.1/internal/bitbucket.org/ww/goautoneg/autoneg_test.go
+pkg/mod/github.com/prometheus/common@v0.9.1/internal/bitbucket.org/ww/goautoneg/autoneg.go
+pkg/mod/github.com/prometheus/common@v0.9.1/internal/bitbucket.org/ww/goautoneg/README.txt
+pkg/mod/github.com/prometheus/common@v0.9.1/log/eventlog_formatter.go
+pkg/mod/github.com/prometheus/common@v0.9.1/log/log_test.go
+pkg/mod/github.com/prometheus/common@v0.9.1/log/log.go
+pkg/mod/github.com/prometheus/common@v0.9.1/log/syslog_formatter_test.go
+pkg/mod/github.com/prometheus/common@v0.9.1/log/syslog_formatter.go
+pkg/mod/github.com/prometheus/common@v0.9.1/model/alert_test.go
+pkg/mod/github.com/prometheus/common@v0.9.1/model/alert.go
+pkg/mod/github.com/prometheus/common@v0.9.1/model/fingerprinting_test.go
+pkg/mod/github.com/prometheus/common@v0.9.1/model/fingerprinting.go
+pkg/mod/github.com/prometheus/common@v0.9.1/model/fnv.go
+pkg/mod/github.com/prometheus/common@v0.9.1/model/labels_test.go
+pkg/mod/github.com/prometheus/common@v0.9.1/model/labels.go
+pkg/mod/github.com/prometheus/common@v0.9.1/model/labelset_test.go
+pkg/mod/github.com/prometheus/common@v0.9.1/model/labelset.go
+pkg/mod/github.com/prometheus/common@v0.9.1/model/metric_test.go
+pkg/mod/github.com/prometheus/common@v0.9.1/model/metric.go
+pkg/mod/github.com/prometheus/common@v0.9.1/model/model.go
+pkg/mod/github.com/prometheus/common@v0.9.1/model/signature_test.go
+pkg/mod/github.com/prometheus/common@v0.9.1/model/signature.go
+pkg/mod/github.com/prometheus/common@v0.9.1/model/silence_test.go
+pkg/mod/github.com/prometheus/common@v0.9.1/model/silence.go
+pkg/mod/github.com/prometheus/common@v0.9.1/model/time_test.go
+pkg/mod/github.com/prometheus/common@v0.9.1/model/time.go
+pkg/mod/github.com/prometheus/common@v0.9.1/model/value_test.go
+pkg/mod/github.com/prometheus/common@v0.9.1/model/value.go
+pkg/mod/github.com/prometheus/common@v0.9.1/promlog/log.go
+pkg/mod/github.com/prometheus/common@v0.9.1/promlog/flag/flag.go
+pkg/mod/github.com/prometheus/common@v0.9.1/route/route_test.go
+pkg/mod/github.com/prometheus/common@v0.9.1/route/route.go
+pkg/mod/github.com/prometheus/common@v0.9.1/server/static_file_server_test.go
+pkg/mod/github.com/prometheus/common@v0.9.1/server/static_file_server.go
+pkg/mod/github.com/prometheus/common@v0.9.1/version/info.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/.gitignore
+pkg/mod/github.com/prometheus/procfs@v0.0.8/.golangci.yml
+pkg/mod/github.com/prometheus/procfs@v0.0.8/arp_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/arp.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/buddyinfo_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/buddyinfo.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/CONTRIBUTING.md
+pkg/mod/github.com/prometheus/procfs@v0.0.8/cpuinfo_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/cpuinfo.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/crypto_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/crypto.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/doc.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/fixtures.ttar
+pkg/mod/github.com/prometheus/procfs@v0.0.8/fs_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/fs.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/go.mod
+pkg/mod/github.com/prometheus/procfs@v0.0.8/go.sum
+pkg/mod/github.com/prometheus/procfs@v0.0.8/ipvs_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/ipvs.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/LICENSE
+pkg/mod/github.com/prometheus/procfs@v0.0.8/MAINTAINERS.md
+pkg/mod/github.com/prometheus/procfs@v0.0.8/Makefile
+pkg/mod/github.com/prometheus/procfs@v0.0.8/Makefile.common
+pkg/mod/github.com/prometheus/procfs@v0.0.8/mdstat_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/mdstat.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/meminfo_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/meminfo.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/mountinfo_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/mountinfo.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/mountstats_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/mountstats.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/net_dev_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/net_dev.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/net_sockstat_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/net_sockstat.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/net_softnet_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/net_softnet.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/net_unix_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/net_unix.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/NOTICE
+pkg/mod/github.com/prometheus/procfs@v0.0.8/proc_environ_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/proc_environ.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/proc_fdinfo_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/proc_fdinfo.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/proc_io_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/proc_io.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/proc_limits_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/proc_limits.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/proc_ns_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/proc_ns.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/proc_psi_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/proc_psi.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/proc_stat_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/proc_stat.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/proc_status_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/proc_status.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/proc_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/proc.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/README.md
+pkg/mod/github.com/prometheus/procfs@v0.0.8/schedstat_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/schedstat.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/stat_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/stat.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/ttar
+pkg/mod/github.com/prometheus/procfs@v0.0.8/vm_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/vm.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/xfrm_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/xfrm.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/zoneinfo_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/zoneinfo.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/.circleci/config.yml
+pkg/mod/github.com/prometheus/procfs@v0.0.8/bcache/bcache.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/bcache/get_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/bcache/get.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/blockdevice/stats_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/blockdevice/stats.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/btrfs/btrfs.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/btrfs/get_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/btrfs/get.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/internal/fs/fs_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/internal/fs/fs.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/internal/util/parse.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/internal/util/readfile.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/internal/util/sysreadfile_compat.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/internal/util/sysreadfile.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/internal/util/valueparser_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/internal/util/valueparser.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/iscsi/get_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/iscsi/get.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/iscsi/iscsi.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/nfs/nfs.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/nfs/parse_nfs_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/nfs/parse_nfs.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/nfs/parse_nfsd_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/nfs/parse_nfsd.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/nfs/parse.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/scripts/check_license.sh
+pkg/mod/github.com/prometheus/procfs@v0.0.8/sysfs/.gitignore
+pkg/mod/github.com/prometheus/procfs@v0.0.8/sysfs/class_cooling_device_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/sysfs/class_cooling_device.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/sysfs/class_infiniband_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/sysfs/class_infiniband.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/sysfs/class_power_supply_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/sysfs/class_power_supply.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/sysfs/class_powercap_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/sysfs/class_powercap.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/sysfs/class_thermal_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/sysfs/class_thermal.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/sysfs/clocksource_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/sysfs/clocksource.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/sysfs/doc.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/sysfs/fs_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/sysfs/fs.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/sysfs/net_class_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/sysfs/net_class.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/sysfs/system_cpu_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/sysfs/system_cpu.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/sysfs/vulnerability.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/xfs/parse_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/xfs/parse.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/xfs/xfs_test.go
+pkg/mod/github.com/prometheus/procfs@v0.0.8/xfs/xfs.go
+pkg/mod/github.com/stretchr/testify@v1.5.1/.gitignore
+pkg/mod/github.com/stretchr/testify@v1.5.1/.travis.gofmt.sh
+pkg/mod/github.com/stretchr/testify@v1.5.1/.travis.gogenerate.sh
+pkg/mod/github.com/stretchr/testify@v1.5.1/.travis.govet.sh
+pkg/mod/github.com/stretchr/testify@v1.5.1/.travis.yml
+pkg/mod/github.com/stretchr/testify@v1.5.1/CONTRIBUTING.md
+pkg/mod/github.com/stretchr/testify@v1.5.1/doc.go
+pkg/mod/github.com/stretchr/testify@v1.5.1/go.mod
+pkg/mod/github.com/stretchr/testify@v1.5.1/go.sum
+pkg/mod/github.com/stretchr/testify@v1.5.1/LICENSE
+pkg/mod/github.com/stretchr/testify@v1.5.1/MAINTAINERS.md
+pkg/mod/github.com/stretchr/testify@v1.5.1/package_test.go
+pkg/mod/github.com/stretchr/testify@v1.5.1/README.md
+pkg/mod/github.com/stretchr/testify@v1.5.1/assert/assertion_format.go
+pkg/mod/github.com/stretchr/testify@v1.5.1/assert/assertion_format.go.tmpl
+pkg/mod/github.com/stretchr/testify@v1.5.1/assert/assertion_forward.go
+pkg/mod/github.com/stretchr/testify@v1.5.1/assert/assertion_forward.go.tmpl
+pkg/mod/github.com/stretchr/testify@v1.5.1/assert/assertion_order_test.go
+pkg/mod/github.com/stretchr/testify@v1.5.1/assert/assertion_order.go
+pkg/mod/github.com/stretchr/testify@v1.5.1/assert/assertions_test.go
+pkg/mod/github.com/stretchr/testify@v1.5.1/assert/assertions.go
+pkg/mod/github.com/stretchr/testify@v1.5.1/assert/doc.go
+pkg/mod/github.com/stretchr/testify@v1.5.1/assert/errors.go
+pkg/mod/github.com/stretchr/testify@v1.5.1/assert/forward_assertions_test.go
+pkg/mod/github.com/stretchr/testify@v1.5.1/assert/forward_assertions.go
+pkg/mod/github.com/stretchr/testify@v1.5.1/assert/http_assertions_test.go
+pkg/mod/github.com/stretchr/testify@v1.5.1/assert/http_assertions.go
+pkg/mod/github.com/stretchr/testify@v1.5.1/http/doc.go
+pkg/mod/github.com/stretchr/testify@v1.5.1/http/test_response_writer.go
+pkg/mod/github.com/stretchr/testify@v1.5.1/http/test_round_tripper.go
+pkg/mod/github.com/stretchr/testify@v1.5.1/mock/doc.go
+pkg/mod/github.com/stretchr/testify@v1.5.1/mock/mock_test.go
+pkg/mod/github.com/stretchr/testify@v1.5.1/mock/mock.go
+pkg/mod/github.com/stretchr/testify@v1.5.1/require/doc.go
+pkg/mod/github.com/stretchr/testify@v1.5.1/require/forward_requirements_test.go
+pkg/mod/github.com/stretchr/testify@v1.5.1/require/forward_requirements.go
+pkg/mod/github.com/stretchr/testify@v1.5.1/require/require_forward.go
+pkg/mod/github.com/stretchr/testify@v1.5.1/require/require_forward.go.tmpl
+pkg/mod/github.com/stretchr/testify@v1.5.1/require/require.go
+pkg/mod/github.com/stretchr/testify@v1.5.1/require/require.go.tmpl
+pkg/mod/github.com/stretchr/testify@v1.5.1/require/requirements_test.go
+pkg/mod/github.com/stretchr/testify@v1.5.1/require/requirements.go
+pkg/mod/github.com/stretchr/testify@v1.5.1/suite/doc.go
+pkg/mod/github.com/stretchr/testify@v1.5.1/suite/interfaces.go
+pkg/mod/github.com/stretchr/testify@v1.5.1/suite/suite_test.go
+pkg/mod/github.com/stretchr/testify@v1.5.1/suite/suite.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/.gitignore
+pkg/mod/github.com/thoas/go-funk@v0.7.0/.travis.yml
+pkg/mod/github.com/thoas/go-funk@v0.7.0/benchmark_test.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/builder_test.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/builder.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/chain_builder_test.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/chain_builder.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/CHANGELOG.md
+pkg/mod/github.com/thoas/go-funk@v0.7.0/compact_test.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/compact.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/example_presence_test.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/fill_test.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/fill.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/funk_test.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/go.mod
+pkg/mod/github.com/thoas/go-funk@v0.7.0/go.sum
+pkg/mod/github.com/thoas/go-funk@v0.7.0/helpers_test.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/helpers.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/intersection_test.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/intersection.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/join_primitives.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/join_test.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/join.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/lazy_builder_test.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/lazy_builder.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/LICENSE
+pkg/mod/github.com/thoas/go-funk@v0.7.0/Makefile
+pkg/mod/github.com/thoas/go-funk@v0.7.0/map_test.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/map.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/max_test.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/max.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/min_test.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/min.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/operation_test.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/operation.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/presence_test.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/presence.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/README.rst
+pkg/mod/github.com/thoas/go-funk@v0.7.0/reduce_test.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/reduce.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/retrieve_test.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/retrieve.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/scan_test.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/scan.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/subset_test.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/subset.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/subtraction_test.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/subtraction.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/transform_test.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/transform.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/typesafe_test.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/typesafe.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/utils_test.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/utils.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/without_test.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/without.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/zip_test.go
+pkg/mod/github.com/thoas/go-funk@v0.7.0/zip.go
+pkg/mod/github.com/valyala/bytebufferpool@v1.0.0/.travis.yml
+pkg/mod/github.com/valyala/bytebufferpool@v1.0.0/bytebuffer_example_test.go
+pkg/mod/github.com/valyala/bytebufferpool@v1.0.0/bytebuffer_test.go
+pkg/mod/github.com/valyala/bytebufferpool@v1.0.0/bytebuffer_timing_test.go
+pkg/mod/github.com/valyala/bytebufferpool@v1.0.0/bytebuffer.go
+pkg/mod/github.com/valyala/bytebufferpool@v1.0.0/doc.go
+pkg/mod/github.com/valyala/bytebufferpool@v1.0.0/LICENSE
+pkg/mod/github.com/valyala/bytebufferpool@v1.0.0/pool_test.go
+pkg/mod/github.com/valyala/bytebufferpool@v1.0.0/pool.go
+pkg/mod/github.com/valyala/bytebufferpool@v1.0.0/README.md
+pkg/mod/github.com/valyala/fasttemplate@v1.0.1/example_test.go
+pkg/mod/github.com/valyala/fasttemplate@v1.0.1/go.mod
+pkg/mod/github.com/valyala/fasttemplate@v1.0.1/go.sum
+pkg/mod/github.com/valyala/fasttemplate@v1.0.1/LICENSE
+pkg/mod/github.com/valyala/fasttemplate@v1.0.1/README.md
+pkg/mod/github.com/valyala/fasttemplate@v1.0.1/template_test.go
+pkg/mod/github.com/valyala/fasttemplate@v1.0.1/template_timing_test.go
+pkg/mod/github.com/valyala/fasttemplate@v1.0.1/template.go
+pkg/mod/github.com/valyala/fasttemplate@v1.0.1/unsafe_gae.go
+pkg/mod/github.com/valyala/fasttemplate@v1.0.1/unsafe.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/.errcheck-excludes
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/.gitignore
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/.gitmodules
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/.lint-whitelist
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/CONTRIBUTING.md
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/Gopkg.lock
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/Gopkg.toml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/LICENSE
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/Makefile
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/README.md
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/THIRD-PARTY-NOTICES
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/.evergreen/config.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/.evergreen/krb5.config
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/benchmark/bson_document.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/benchmark/bson_map.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/benchmark/bson_struct.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/benchmark/bson_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/benchmark/bson_types.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/benchmark/bson.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/benchmark/canary_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/benchmark/canary.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/benchmark/harness_case.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/benchmark/harness_main.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/benchmark/harness_results.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/benchmark/harness.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/benchmark/multi_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/benchmark/multi.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/benchmark/single_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/benchmark/single.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/benchmark_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bson_1_8.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bson_corpus_spec_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bson_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bson.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/decoder_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/decoder.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/doc.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/encoder_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/encoder.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/marshal_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/marshal.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/marshaling_cases_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/primitive_codecs_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/primitive_codecs.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/raw_element.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/raw_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/raw_value_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/raw_value.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/raw.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/registry.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/truncation_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/types.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/unmarshal_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/unmarshal.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/unmarshaling_cases_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bsoncodec/bsoncodec_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bsoncodec/bsoncodec.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bsoncodec/default_value_decoders_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bsoncodec/default_value_decoders.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bsoncodec/default_value_encoders_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bsoncodec/default_value_encoders.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bsoncodec/doc.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bsoncodec/mode.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bsoncodec/pointer_codec.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bsoncodec/proxy.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bsoncodec/registry_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bsoncodec/registry.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bsoncodec/struct_codec_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bsoncodec/struct_codec.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bsoncodec/struct_tag_parser_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bsoncodec/struct_tag_parser.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bsoncodec/types.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bsonrw/bsonrw_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bsonrw/copier_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bsonrw/copier.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bsonrw/doc.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bsonrw/extjson_parser_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bsonrw/extjson_parser.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bsonrw/extjson_reader_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bsonrw/extjson_reader.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bsonrw/extjson_tables.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bsonrw/extjson_wrappers.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bsonrw/extjson_writer_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bsonrw/extjson_writer.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bsonrw/json_scanner_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bsonrw/json_scanner.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bsonrw/mode.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bsonrw/reader.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bsonrw/value_reader_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bsonrw/value_reader_writer_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bsonrw/value_reader.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bsonrw/value_writer_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bsonrw/value_writer.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bsonrw/writer.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bsonrw/bsonrwtest/bsonrwtest.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bsontype/bsontype_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/bsontype/bsontype.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/primitive/decimal.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/primitive/objectid_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/primitive/objectid.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/primitive/primitive_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/bson/primitive/primitive.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/cmd/docbuilder/main.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/cmd/godriver-benchmark/main.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/cmd/operationgen/main.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/cmd/operationgen/README.md
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/array.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/binary.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/boolean.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/bsonview
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/code_w_scope.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/code.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/datetime.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/dbpointer.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/dbref.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/decimal128-1.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/decimal128-2.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/decimal128-3.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/decimal128-4.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/decimal128-5.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/decimal128-6.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/decimal128-7.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/document.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/double.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/int32.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/int64.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/maxkey.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/minkey.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/multi-type-deprecated.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/multi-type.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/null.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/oid.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/regex.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/string.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/symbol.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/timestamp.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/top.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/undefined.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/auth/connection-string.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/auth/connection-string.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/auth/README.rst
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/bson-corpus/array.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/bson-corpus/binary.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/bson-corpus/boolean.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/bson-corpus/bsonview
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/bson-corpus/code_w_scope.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/bson-corpus/code.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/bson-corpus/datetime.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/bson-corpus/dbpointer.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/bson-corpus/dbref.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/bson-corpus/decimal128-1.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/bson-corpus/decimal128-2.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/bson-corpus/decimal128-3.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/bson-corpus/decimal128-4.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/bson-corpus/decimal128-5.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/bson-corpus/decimal128-6.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/bson-corpus/decimal128-7.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/bson-corpus/document.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/bson-corpus/double.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/bson-corpus/int32.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/bson-corpus/int64.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/bson-corpus/maxkey.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/bson-corpus/minkey.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/bson-corpus/multi-type-deprecated.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/bson-corpus/multi-type.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/bson-corpus/null.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/bson-corpus/oid.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/bson-corpus/regex.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/bson-corpus/string.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/bson-corpus/symbol.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/bson-corpus/timestamp.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/bson-corpus/top.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/bson-corpus/undefined.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/certificates/ca.pem
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/certificates/client.pem
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/certificates/server.pem
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/change-streams/change-streams-errors.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/change-streams/change-streams-errors.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/change-streams/change-streams.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/change-streams/change-streams.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/change-streams/README.rst
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/command-monitoring/bulkWrite.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/command-monitoring/bulkWrite.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/command-monitoring/command.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/command-monitoring/command.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/command-monitoring/deleteMany.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/command-monitoring/deleteMany.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/command-monitoring/deleteOne.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/command-monitoring/deleteOne.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/command-monitoring/find.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/command-monitoring/find.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/command-monitoring/insertMany.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/command-monitoring/insertMany.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/command-monitoring/insertOne.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/command-monitoring/insertOne.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/command-monitoring/README.rst
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/command-monitoring/unacknowledgedBulkWrite.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/command-monitoring/unacknowledgedBulkWrite.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/command-monitoring/updateMany.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/command-monitoring/updateMany.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/command-monitoring/updateOne.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/command-monitoring/updateOne.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-monitoring-and-pooling/connection-monitoring-and-pooling.rst
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-monitoring-and-pooling/connection-must-have-id.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-monitoring-and-pooling/connection-must-have-id.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-monitoring-and-pooling/connection-must-order-ids.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-monitoring-and-pooling/connection-must-order-ids.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-monitoring-and-pooling/pool-checkin-destroy-closed.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-monitoring-and-pooling/pool-checkin-destroy-closed.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-monitoring-and-pooling/pool-checkin-destroy-stale.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-monitoring-and-pooling/pool-checkin-destroy-stale.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-monitoring-and-pooling/pool-checkin-make-available.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-monitoring-and-pooling/pool-checkin-make-available.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-monitoring-and-pooling/pool-checkin.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-monitoring-and-pooling/pool-checkin.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-monitoring-and-pooling/pool-checkout-connection.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-monitoring-and-pooling/pool-checkout-connection.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-monitoring-and-pooling/pool-checkout-error-closed.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-monitoring-and-pooling/pool-checkout-error-closed.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-monitoring-and-pooling/pool-checkout-multiple.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-monitoring-and-pooling/pool-checkout-multiple.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-monitoring-and-pooling/pool-checkout-no-idle.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-monitoring-and-pooling/pool-checkout-no-idle.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-monitoring-and-pooling/pool-checkout-no-stale.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-monitoring-and-pooling/pool-checkout-no-stale.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-monitoring-and-pooling/pool-close-destroy-conns.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-monitoring-and-pooling/pool-close-destroy-conns.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-monitoring-and-pooling/pool-close.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-monitoring-and-pooling/pool-close.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-monitoring-and-pooling/pool-create-max-size.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-monitoring-and-pooling/pool-create-max-size.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-monitoring-and-pooling/pool-create-min-size.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-monitoring-and-pooling/pool-create-min-size.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-monitoring-and-pooling/pool-create-with-options.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-monitoring-and-pooling/pool-create-with-options.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-monitoring-and-pooling/pool-create.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-monitoring-and-pooling/pool-create.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-monitoring-and-pooling/README.rst
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-monitoring-and-pooling/wait-queue-fairness.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-monitoring-and-pooling/wait-queue-fairness.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-monitoring-and-pooling/wait-queue-timeout.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-monitoring-and-pooling/wait-queue-timeout.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-string/invalid-uris.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-string/invalid-uris.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-string/README.rst
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-string/valid-auth.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-string/valid-auth.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-string/valid-db-with-dotted-name.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-string/valid-db-with-dotted-name.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-string/valid-host_identifiers.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-string/valid-host_identifiers.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-string/valid-options.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-string/valid-options.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-string/valid-unix_socket-absolute.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-string/valid-unix_socket-absolute.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-string/valid-unix_socket-relative.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-string/valid-unix_socket-relative.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-string/valid-warnings.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/connection-string/valid-warnings.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/convenient-transactions/callback-aborts.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/convenient-transactions/callback-aborts.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/convenient-transactions/callback-commits.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/convenient-transactions/callback-commits.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/convenient-transactions/callback-retry.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/convenient-transactions/callback-retry.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/convenient-transactions/commit-retry.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/convenient-transactions/commit-retry.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/convenient-transactions/commit-transienttransactionerror-4.2.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/convenient-transactions/commit-transienttransactionerror-4.2.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/convenient-transactions/commit-transienttransactionerror.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/convenient-transactions/commit-transienttransactionerror.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/convenient-transactions/commit-writeconcernerror.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/convenient-transactions/commit-writeconcernerror.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/convenient-transactions/commit.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/convenient-transactions/commit.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/convenient-transactions/README.rst
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/convenient-transactions/transaction-options.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/convenient-transactions/transaction-options.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/README.rst
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/read/aggregate-collation.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/read/aggregate-collation.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/read/aggregate-out.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/read/aggregate-out.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/read/aggregate.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/read/aggregate.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/read/count-collation.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/read/count-collation.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/read/count.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/read/count.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/read/distinct-collation.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/read/distinct-collation.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/read/distinct.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/read/distinct.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/read/find-collation.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/read/find-collation.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/read/find.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/read/find.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/bulkWrite-arrayFilters.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/bulkWrite-arrayFilters.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/bulkWrite-collation.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/bulkWrite-collation.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/bulkWrite.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/bulkWrite.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/deleteMany-collation.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/deleteMany-collation.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/deleteMany.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/deleteMany.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/deleteOne-collation.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/deleteOne-collation.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/deleteOne.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/deleteOne.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/findOneAndDelete-collation.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/findOneAndDelete-collation.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/findOneAndDelete.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/findOneAndDelete.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/findOneAndReplace-collation.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/findOneAndReplace-collation.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/findOneAndReplace-upsert.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/findOneAndReplace-upsert.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/findOneAndReplace.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/findOneAndReplace.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/findOneAndUpdate-arrayFilters.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/findOneAndUpdate-arrayFilters.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/findOneAndUpdate-collation.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/findOneAndUpdate-collation.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/findOneAndUpdate.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/findOneAndUpdate.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/insertMany.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/insertMany.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/insertOne.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/insertOne.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/replaceOne-collation.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/replaceOne-collation.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/replaceOne.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/replaceOne.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/updateMany-arrayFilters.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/updateMany-arrayFilters.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/updateMany-collation.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/updateMany-collation.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/updateMany.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/updateMany.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/updateOne-arrayFilters.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/updateOne-arrayFilters.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/updateOne-collation.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/updateOne-collation.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/updateOne.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v1/write/updateOne.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v2/aggregate-merge.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v2/aggregate-merge.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v2/aggregate-out-readConcern.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v2/aggregate-out-readConcern.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v2/db-aggregate.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v2/db-aggregate.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v2/updateWithPipelines.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/crud/v2/updateWithPipelines.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/extended_bson/deep_bson.json.gz
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/extended_bson/flat_bson.json.gz
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/extended_bson/full_bson.json.gz
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/gridfs/delete.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/gridfs/delete.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/gridfs/download_by_name.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/gridfs/download_by_name.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/gridfs/download.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/gridfs/download.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/gridfs/upload.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/gridfs/upload.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/longer-parent-in-return.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/longer-parent-in-return.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/misformatted-option.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/misformatted-option.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/no-results.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/no-results.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/not-enough-parts.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/not-enough-parts.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/one-result-default-port.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/one-result-default-port.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/one-txt-record-multiple-strings.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/one-txt-record-multiple-strings.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/one-txt-record.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/one-txt-record.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/parent-part-mismatch1.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/parent-part-mismatch1.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/parent-part-mismatch2.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/parent-part-mismatch2.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/parent-part-mismatch3.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/parent-part-mismatch3.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/parent-part-mismatch4.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/parent-part-mismatch4.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/parent-part-mismatch5.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/parent-part-mismatch5.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/README.rst
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/returned-parent-too-short.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/returned-parent-too-short.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/returned-parent-wrong.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/returned-parent-wrong.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/two-results-default-port.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/two-results-default-port.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/two-results-nonstandard-port.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/two-results-nonstandard-port.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/two-txt-records.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/two-txt-records.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/txt-record-not-allowed-option.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/txt-record-not-allowed-option.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/txt-record-with-overridden-ssl-option.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/txt-record-with-overridden-ssl-option.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/txt-record-with-overridden-uri-option.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/txt-record-with-overridden-uri-option.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/txt-record-with-unallowed-option.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/txt-record-with-unallowed-option.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/uri-with-port.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/uri-with-port.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/uri-with-two-hosts.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/initial-dns-seedlist-discovery/uri-with-two-hosts.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/README.rst
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetNoPrimary/DefaultNoMaxStaleness.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetNoPrimary/DefaultNoMaxStaleness.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetNoPrimary/Incompatible.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetNoPrimary/Incompatible.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetNoPrimary/LastUpdateTime.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetNoPrimary/LastUpdateTime.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetNoPrimary/Nearest.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetNoPrimary/Nearest.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetNoPrimary/Nearest2.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetNoPrimary/Nearest2.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetNoPrimary/NoKnownServers.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetNoPrimary/NoKnownServers.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetNoPrimary/PrimaryPreferred_tags.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetNoPrimary/PrimaryPreferred_tags.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetNoPrimary/PrimaryPreferred.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetNoPrimary/PrimaryPreferred.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetNoPrimary/Secondary.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetNoPrimary/Secondary.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetNoPrimary/SecondaryPreferred_tags.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetNoPrimary/SecondaryPreferred_tags.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetNoPrimary/SecondaryPreferred.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetNoPrimary/SecondaryPreferred.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetNoPrimary/ZeroMaxStaleness.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetNoPrimary/ZeroMaxStaleness.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetWithPrimary/DefaultNoMaxStaleness.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetWithPrimary/DefaultNoMaxStaleness.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetWithPrimary/Incompatible.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetWithPrimary/Incompatible.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetWithPrimary/LastUpdateTime.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetWithPrimary/LastUpdateTime.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetWithPrimary/LongHeartbeat.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetWithPrimary/LongHeartbeat.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetWithPrimary/LongHeartbeat2.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetWithPrimary/LongHeartbeat2.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetWithPrimary/MaxStalenessTooSmall.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetWithPrimary/MaxStalenessTooSmall.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetWithPrimary/MaxStalenessWithModePrimary.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetWithPrimary/MaxStalenessWithModePrimary.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetWithPrimary/Nearest_tags.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetWithPrimary/Nearest_tags.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetWithPrimary/Nearest.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetWithPrimary/Nearest.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetWithPrimary/Nearest2.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetWithPrimary/Nearest2.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetWithPrimary/PrimaryPreferred_incompatible.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetWithPrimary/PrimaryPreferred_incompatible.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetWithPrimary/PrimaryPreferred.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetWithPrimary/PrimaryPreferred.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetWithPrimary/Secondary_tags.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetWithPrimary/Secondary_tags.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetWithPrimary/Secondary_tags2.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetWithPrimary/Secondary_tags2.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetWithPrimary/SecondaryPreferred_tags.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetWithPrimary/SecondaryPreferred_tags.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetWithPrimary/SecondaryPreferred_tags2.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetWithPrimary/SecondaryPreferred_tags2.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetWithPrimary/SecondaryPreferred.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetWithPrimary/SecondaryPreferred.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetWithPrimary/ZeroMaxStaleness.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/ReplicaSetWithPrimary/ZeroMaxStaleness.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/Sharded/Incompatible.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/Sharded/Incompatible.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/Sharded/SmallMaxStaleness.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/Sharded/SmallMaxStaleness.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/Single/Incompatible.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/Single/Incompatible.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/Single/SmallMaxStaleness.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/Single/SmallMaxStaleness.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/Unknown/SmallMaxStaleness.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/max-staleness/Unknown/SmallMaxStaleness.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/read-write-concern/README.rst
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/read-write-concern/connection-string/read-concern.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/read-write-concern/connection-string/read-concern.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/read-write-concern/connection-string/write-concern.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/read-write-concern/connection-string/write-concern.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/read-write-concern/document/read-concern.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/read-write-concern/document/read-concern.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/read-write-concern/document/write-concern.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/read-write-concern/document/write-concern.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/aggregate-merge.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/aggregate-merge.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/aggregate-serverErrors.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/aggregate-serverErrors.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/aggregate.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/aggregate.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/changeStreams-client.watch-serverErrors.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/changeStreams-client.watch-serverErrors.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/changeStreams-client.watch.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/changeStreams-client.watch.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/changeStreams-db.coll.watch-serverErrors.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/changeStreams-db.coll.watch-serverErrors.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/changeStreams-db.coll.watch.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/changeStreams-db.coll.watch.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/changeStreams-db.watch-serverErrors.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/changeStreams-db.watch-serverErrors.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/changeStreams-db.watch.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/changeStreams-db.watch.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/count-serverErrors.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/count-serverErrors.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/count.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/count.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/countDocuments-serverErrors.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/countDocuments-serverErrors.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/countDocuments.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/countDocuments.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/distinct-serverErrors.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/distinct-serverErrors.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/distinct.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/distinct.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/estimatedDocumentCount-serverErrors.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/estimatedDocumentCount-serverErrors.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/estimatedDocumentCount.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/estimatedDocumentCount.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/find-serverErrors.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/find-serverErrors.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/find.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/find.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/findOne-serverErrors.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/findOne-serverErrors.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/findOne.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/findOne.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/gridfs-download-serverErrors.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/gridfs-download-serverErrors.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/gridfs-download.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/gridfs-download.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/gridfs-downloadByName-serverErrors.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/gridfs-downloadByName-serverErrors.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/gridfs-downloadByName.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/gridfs-downloadByName.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/listCollectionNames-serverErrors.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/listCollectionNames-serverErrors.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/listCollectionNames.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/listCollectionNames.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/listCollectionObjects-serverErrors.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/listCollectionObjects-serverErrors.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/listCollectionObjects.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/listCollectionObjects.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/listCollections-serverErrors.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/listCollections-serverErrors.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/listCollections.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/listCollections.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/listDatabaseNames-serverErrors.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/listDatabaseNames-serverErrors.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/listDatabaseNames.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/listDatabaseNames.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/listDatabaseObjects-serverErrors.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/listDatabaseObjects-serverErrors.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/listDatabaseObjects.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/listDatabaseObjects.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/listDatabases-serverErrors.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/listDatabases-serverErrors.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/listDatabases.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/listDatabases.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/listIndexes-serverErrors.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/listIndexes-serverErrors.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/listIndexes.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/listIndexes.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/listIndexNames-serverErrors.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/listIndexNames-serverErrors.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/listIndexNames.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/listIndexNames.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/mapReduce.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-reads/mapReduce.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-writes/bulkWrite-serverErrors.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-writes/bulkWrite-serverErrors.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-writes/bulkWrite.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-writes/bulkWrite.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-writes/deleteMany.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-writes/deleteMany.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-writes/deleteOne-serverErrors.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-writes/deleteOne-serverErrors.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-writes/deleteOne.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-writes/deleteOne.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-writes/findOneAndDelete-serverErrors.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-writes/findOneAndDelete-serverErrors.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-writes/findOneAndDelete.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-writes/findOneAndDelete.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-writes/findOneAndReplace-serverErrors.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-writes/findOneAndReplace-serverErrors.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-writes/findOneAndReplace.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-writes/findOneAndReplace.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-writes/findOneAndUpdate-serverErrors.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-writes/findOneAndUpdate-serverErrors.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-writes/findOneAndUpdate.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-writes/findOneAndUpdate.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-writes/insertMany-serverErrors.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-writes/insertMany-serverErrors.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-writes/insertMany.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-writes/insertMany.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-writes/insertOne-serverErrors.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-writes/insertOne-serverErrors.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-writes/insertOne.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-writes/insertOne.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-writes/README.rst
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-writes/replaceOne-serverErrors.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-writes/replaceOne-serverErrors.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-writes/replaceOne.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-writes/replaceOne.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-writes/updateMany.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-writes/updateMany.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-writes/updateOne-serverErrors.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-writes/updateOne-serverErrors.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-writes/updateOne.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/retryable-writes/updateOne.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/README.rst
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/monitoring/README.rst
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/monitoring/replica_set_with_no_primary.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/monitoring/replica_set_with_no_primary.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/monitoring/replica_set_with_primary.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/monitoring/replica_set_with_primary.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/monitoring/replica_set_with_removal.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/monitoring/replica_set_with_removal.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/monitoring/required_replica_set.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/monitoring/required_replica_set.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/monitoring/standalone.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/monitoring/standalone.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/compatible_unknown.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/compatible_unknown.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/compatible.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/compatible.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/discover_arbiters.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/discover_arbiters.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/discover_passives.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/discover_passives.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/discover_primary.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/discover_primary.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/discover_secondary.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/discover_secondary.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/discovery.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/discovery.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/equal_electionids.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/equal_electionids.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/ghost_discovered.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/ghost_discovered.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/hosts_differ_from_seeds.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/hosts_differ_from_seeds.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/incompatible_arbiter.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/incompatible_arbiter.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/incompatible_ghost.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/incompatible_ghost.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/incompatible_other.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/incompatible_other.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/ls_timeout.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/ls_timeout.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/member_reconfig.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/member_reconfig.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/member_standalone.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/member_standalone.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/new_primary_new_electionid.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/new_primary_new_electionid.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/new_primary_new_setversion.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/new_primary_new_setversion.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/new_primary_wrong_set_name.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/new_primary_wrong_set_name.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/new_primary.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/new_primary.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/non_rs_member.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/non_rs_member.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/normalize_case_me.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/normalize_case_me.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/normalize_case.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/normalize_case.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/null_election_id.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/null_election_id.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/primary_becomes_ghost.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/primary_becomes_ghost.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/primary_becomes_mongos.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/primary_becomes_mongos.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/primary_becomes_standalone.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/primary_becomes_standalone.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/primary_changes_set_name.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/primary_changes_set_name.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/primary_disconnect_electionid.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/primary_disconnect_electionid.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/primary_disconnect_setversion.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/primary_disconnect_setversion.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/primary_disconnect.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/primary_disconnect.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/primary_hint_from_secondary_with_mismatched_me.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/primary_hint_from_secondary_with_mismatched_me.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/primary_mismatched_me.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/primary_mismatched_me.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/primary_reports_new_member.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/primary_reports_new_member.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/primary_to_no_primary_mismatched_me.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/primary_to_no_primary_mismatched_me.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/primary_wrong_set_name.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/primary_wrong_set_name.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/response_from_removed.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/response_from_removed.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/rsother_discovered.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/rsother_discovered.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/sec_not_auth.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/sec_not_auth.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/secondary_ignore_ok_0.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/secondary_ignore_ok_0.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/secondary_mismatched_me.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/secondary_mismatched_me.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/secondary_wrong_set_name_with_primary.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/secondary_wrong_set_name_with_primary.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/secondary_wrong_set_name.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/secondary_wrong_set_name.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/setversion_without_electionid.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/setversion_without_electionid.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/stepdown_change_set_name.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/stepdown_change_set_name.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/too_new.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/too_new.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/too_old.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/too_old.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/unexpected_mongos.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/unexpected_mongos.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/use_setversion_without_electionid.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/use_setversion_without_electionid.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/wrong_set_name.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/rs/wrong_set_name.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/sharded/compatible.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/sharded/compatible.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/sharded/ls_timeout_mongos.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/sharded/ls_timeout_mongos.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/sharded/mongos_disconnect.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/sharded/mongos_disconnect.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/sharded/multiple_mongoses.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/sharded/multiple_mongoses.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/sharded/non_mongos_removed.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/sharded/non_mongos_removed.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/sharded/normalize_uri_case.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/sharded/normalize_uri_case.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/sharded/too_new.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/sharded/too_new.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/sharded/too_old.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/sharded/too_old.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/single/compatible.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/single/compatible.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/single/direct_connection_external_ip.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/single/direct_connection_external_ip.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/single/direct_connection_mongos.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/single/direct_connection_mongos.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/single/direct_connection_rsarbiter.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/single/direct_connection_rsarbiter.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/single/direct_connection_rsprimary.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/single/direct_connection_rsprimary.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/single/direct_connection_rssecondary.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/single/direct_connection_rssecondary.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/single/direct_connection_slave.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/single/direct_connection_slave.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/single/direct_connection_standalone.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/single/direct_connection_standalone.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/single/ls_timeout_standalone.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/single/ls_timeout_standalone.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/single/not_ok_response.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/single/not_ok_response.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/single/standalone_removed.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/single/standalone_removed.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/single/too_new.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/single/too_new.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/single/too_old.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/single/too_old.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/single/unavailable_seed.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-discovery-and-monitoring/single/unavailable_seed.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/README.rst
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/rtt/first_value_zero.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/rtt/first_value_zero.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/rtt/first_value.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/rtt/first_value.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/rtt/value_test_1.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/rtt/value_test_1.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/rtt/value_test_2.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/rtt/value_test_2.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/rtt/value_test_3.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/rtt/value_test_3.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/rtt/value_test_4.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/rtt/value_test_4.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/rtt/value_test_5.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/rtt/value_test_5.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetNoPrimary/read/Nearest_multiple.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetNoPrimary/read/Nearest_multiple.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetNoPrimary/read/Nearest_non_matching.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetNoPrimary/read/Nearest_non_matching.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetNoPrimary/read/Nearest.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetNoPrimary/read/Nearest.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetNoPrimary/read/PossiblePrimary.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetNoPrimary/read/PossiblePrimary.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetNoPrimary/read/PossiblePrimaryNearest.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetNoPrimary/read/PossiblePrimaryNearest.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetNoPrimary/read/Primary.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetNoPrimary/read/Primary.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetNoPrimary/read/PrimaryPreferred_non_matching.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetNoPrimary/read/PrimaryPreferred_non_matching.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetNoPrimary/read/PrimaryPreferred.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetNoPrimary/read/PrimaryPreferred.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetNoPrimary/read/Secondary_multi_tags.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetNoPrimary/read/Secondary_multi_tags.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetNoPrimary/read/Secondary_multi_tags2.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetNoPrimary/read/Secondary_multi_tags2.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetNoPrimary/read/Secondary_non_matching.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetNoPrimary/read/Secondary_non_matching.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetNoPrimary/read/Secondary.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetNoPrimary/read/Secondary.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetNoPrimary/read/SecondaryPreferred_non_matching.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetNoPrimary/read/SecondaryPreferred_non_matching.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetNoPrimary/read/SecondaryPreferred.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetNoPrimary/read/SecondaryPreferred.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetNoPrimary/write/SecondaryPreferred.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetNoPrimary/write/SecondaryPreferred.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetWithPrimary/read/Nearest_multiple.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetWithPrimary/read/Nearest_multiple.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetWithPrimary/read/Nearest_non_matching.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetWithPrimary/read/Nearest_non_matching.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetWithPrimary/read/Nearest.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetWithPrimary/read/Nearest.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetWithPrimary/read/Primary.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetWithPrimary/read/Primary.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetWithPrimary/read/PrimaryPreferred_non_matching.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetWithPrimary/read/PrimaryPreferred_non_matching.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetWithPrimary/read/PrimaryPreferred.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetWithPrimary/read/PrimaryPreferred.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetWithPrimary/read/Secondary_non_matching.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetWithPrimary/read/Secondary_non_matching.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetWithPrimary/read/Secondary.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetWithPrimary/read/Secondary.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetWithPrimary/read/SecondaryPreferred_non_matching.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetWithPrimary/read/SecondaryPreferred_non_matching.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetWithPrimary/read/SecondaryPreferred_tags.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetWithPrimary/read/SecondaryPreferred_tags.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetWithPrimary/read/SecondaryPreferred.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetWithPrimary/read/SecondaryPreferred.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetWithPrimary/write/SecondaryPreferred.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/ReplicaSetWithPrimary/write/SecondaryPreferred.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/Sharded/read/SecondaryPreferred.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/Sharded/read/SecondaryPreferred.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/Sharded/write/SecondaryPreferred.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/Sharded/write/SecondaryPreferred.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/Single/read/SecondaryPreferred.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/Single/read/SecondaryPreferred.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/Single/write/SecondaryPreferred.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/Single/write/SecondaryPreferred.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/Unknown/read/SecondaryPreferred.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/Unknown/read/SecondaryPreferred.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/Unknown/write/SecondaryPreferred.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/server-selection/server_selection/Unknown/write/SecondaryPreferred.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/sessions/dirty-session-errors.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/sessions/dirty-session-errors.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/sessions/README.rst
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/single_and_multi_document/large_doc.json.gz
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/single_and_multi_document/small_doc.json.gz
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/single_and_multi_document/tweet.json.gz
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/abort.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/abort.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/bulk.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/bulk.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/causal-consistency.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/causal-consistency.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/commit.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/commit.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/count.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/count.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/delete.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/delete.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/error-labels.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/error-labels.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/errors.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/errors.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/findOneAndDelete.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/findOneAndDelete.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/findOneAndReplace.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/findOneAndReplace.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/findOneAndUpdate.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/findOneAndUpdate.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/insert.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/insert.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/isolation.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/isolation.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/mongos-pin-auto-tests.py
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/mongos-pin-auto.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/mongos-pin-auto.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/mongos-recovery-token.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/mongos-recovery-token.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/pin-mongos.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/pin-mongos.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/read-concern.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/read-concern.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/read-pref.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/read-pref.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/README.rst
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/reads.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/reads.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/retryable-abort.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/retryable-abort.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/retryable-commit.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/retryable-commit.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/retryable-writes.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/retryable-writes.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/run-command.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/run-command.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/transaction-options.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/transaction-options.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/update.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/update.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/write-concern.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/transactions/write-concern.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/uri-options/auth-options.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/uri-options/auth-options.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/uri-options/ca.pem
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/uri-options/cert.pem
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/uri-options/client.pem
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/uri-options/compression-options.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/uri-options/compression-options.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/uri-options/concern-options.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/uri-options/concern-options.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/uri-options/connection-options.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/uri-options/connection-options.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/uri-options/connection-pool-options.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/uri-options/connection-pool-options.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/uri-options/read-preference-options.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/uri-options/read-preference-options.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/uri-options/README.rst
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/uri-options/single-threaded-options.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/uri-options/single-threaded-options.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/uri-options/tls-options.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/data/uri-options/tls-options.yml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/etc/add-license.sh
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/etc/check_env.sh
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/etc/check_fmt.sh
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/etc/generate-notices.pl
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/etc/lintscreen.pl
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/etc/list_pkgs.sh
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/etc/list_test_pkgs.sh
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/etc/update-spec-tests.sh
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/etc/assets/docs-mongodb-green.svg
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/etc/assets/godoc-bson-blue.svg
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/etc/assets/godoc-mongo-blue.svg
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/etc/assets/mongo-gopher.png
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/event/monitoring.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/examples/documentation_examples/examples_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/examples/documentation_examples/examples.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/internal/const.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/internal/error.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/internal/semaphore_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/internal/semaphore.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/internal/testutil/config.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/internal/testutil/ops.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/internal/testutil/helpers/helpers.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/internal/testutil/israce/norace.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/internal/testutil/israce/race.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/batch_cursor.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/bulk_write_models.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/bulk_write.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/causal_consistency_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/change_stream_spec_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/change_stream_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/change_stream.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/client_internal_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/client_options_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/client_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/client.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/collection_internal_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/collection.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/command_monitoring_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/crud_spec_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/crud_spec_v2_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/crud_util_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/cursor_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/cursor.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/database_internal_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/database_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/database.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/doc.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/errors.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/index_options_builder.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/index_view_internal_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/index_view.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/mongo_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/mongo.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/operation_legacy_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/primary_stepdown_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/read_write_concern_spec_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/results_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/results.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/retryable_reads_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/retryable_writes_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/session.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/sessions_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/single_result_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/single_result.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/transaction_mongos_pinning_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/transactions_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/util.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/with_transactions_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/gridfs/bucket.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/gridfs/download_stream.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/gridfs/gridfs_retryable_spec_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/gridfs/gridfs_spec_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/gridfs/gridfs_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/gridfs/gridfs_util_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/gridfs/upload_stream.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/options/aggregateoptions.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/options/bulkwriteoptions.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/options/changestreamoptions.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/options/clientoptions_1_9.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/options/clientoptions_1_10.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/options/clientoptions_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/options/clientoptions.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/options/collation_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/options/collectionoptions.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/options/countoptions.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/options/dboptions.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/options/deleteoptions.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/options/distinctoptions.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/options/estimatedcountoptions.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/options/findoptions.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/options/gridfsoptions.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/options/indexoptions.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/options/insertoptions.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/options/listcollectionsoptions.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/options/listdatabasesoptions.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/options/mongooptions.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/options/replaceoptions.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/options/runcmdoptions.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/options/sessionoptions.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/options/transactionoptions.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/options/updateoptions.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/options/testdata/ca-key.pem
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/options/testdata/ca.pem
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/options/testdata/cert.pem
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/options/testdata/certificate.pem
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/options/testdata/csr.json
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/options/testdata/key.pem
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/options/testdata/nopass/cert.pem
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/options/testdata/nopass/certificate.pem
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/options/testdata/nopass/key.pem
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/readconcern/readconcern.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/readpref/mode.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/readpref/options.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/readpref/readpref_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/readpref/readpref.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/testatlas/main.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/writeconcern/writeconcern_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/mongo/writeconcern/writeconcern.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/tag/tag_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/tag/tag.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/version/version.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/README.md
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/bsonx/array_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/bsonx/array.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/bsonx/bson_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/bsonx/constructor.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/bsonx/document_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/bsonx/document.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/bsonx/element_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/bsonx/element.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/bsonx/mdocument_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/bsonx/mdocument.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/bsonx/primitive_codecs_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/bsonx/primitive_codecs.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/bsonx/registry.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/bsonx/value_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/bsonx/value.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/bsonx/bsoncore/bsoncore_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/bsonx/bsoncore/bsoncore.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/bsonx/bsoncore/document_sequence_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/bsonx/bsoncore/document_sequence.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/bsonx/bsoncore/document_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/bsonx/bsoncore/document.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/bsonx/bsoncore/element_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/bsonx/bsoncore/element.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/bsonx/bsoncore/tables.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/bsonx/bsoncore/value_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/bsonx/bsoncore/value.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/batch_cursor.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/batches_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/batches.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/DESIGN.md
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/driver.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/errors.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/address/addr_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/address/addr.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/auth/auth_spec_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/auth/auth_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/auth/auth.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/auth/cred.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/auth/default.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/auth/doc.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/auth/gssapi_not_enabled.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/auth/gssapi_not_supported.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/auth/gssapi_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/auth/gssapi.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/auth/mongodbcr_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/auth/mongodbcr.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/auth/plain_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/auth/plain.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/auth/sasl.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/auth/scram.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/auth/util.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/auth/x509.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/auth/internal/gssapi/gss_wrapper.c
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/auth/internal/gssapi/gss_wrapper.h
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/auth/internal/gssapi/gss.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/auth/internal/gssapi/sspi_wrapper.c
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/auth/internal/gssapi/sspi_wrapper.h
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/auth/internal/gssapi/sspi.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/connstring/connstring_spec_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/connstring/connstring_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/connstring/connstring.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/description/description.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/description/feature_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/description/feature.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/description/max_staleness_spec_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/description/selector_spec_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/description/selector_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/description/selector_write_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/description/server_kind.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/description/server_selector.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/description/server.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/description/shared_spec_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/description/topology_kind.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/description/topology.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/description/version_range_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/description/version_range.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/description/version_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/description/version.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/dns/dns.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/drivergen/drivergen_test.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/drivergen/drivergen.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/drivergen/example.operation.toml
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/drivergen/templates.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/drivergen/templates/command_parameter.tmpl
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/drivergen/templates/operation.tmpl
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/drivergen/templates/response_field.tmpl
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/drivertest/channel_conn.go
+pkg/mod/go.mongodb.org/mongo-driver@v1.1.1/x/mongo/driver/drivertest/channel_netconn.go
diff --git a/CODEOWNERS b/CODEOWNERS
index 90dc6527c8b2..b8fceb851111 100644
--- a/CODEOWNERS
+++ b/CODEOWNERS
@@ -3,16 +3,17 @@ circleci/ @tmdzk @mattymo @119Vik
ci-scripts/ @rdefosse @tmdzk @mattymo @119Vik
-*/cloud/ @magma/orc8r-approvers
+*/cloud/ @magma/orc8r-approvers
.golangci.yml @magma/orc8r-approvers
-orc8r/ @magma/orc8r-approvers
+orc8r/ @magma/orc8r-approvers
orc8r/tools/packer/ @tmdzk @mattymo @119Vik
orc8r/cloud/deploy/bare-metal/ @tmdzk @mattymo @119Vik
+orc8r/cloud/deploy/bare-metal-ansible/ @mattymo @119Vik
orc8r/gateway/c/ @themarwhal @ardzoht
-feg/ @magma/feg-approvers
+feg/ @magma/feg-approvers
cwf/ @themarwhal @mpgermano @uri200 @emakeev
cwf/gateway/Vagrantfile @mattymo @119Vik @tmdzk
@@ -38,6 +39,6 @@ lte/gateway/Vagrantfile @mattymo @119Vik @tmdzk
xwf/ @AyliD @aharonnovo @r-i-g
feg/radius @AyliD @aharonnovo @r-i-g @themarwhal @mpgermano @uri200 @emakeev
-nms/ @karthiksubraveti @andreilee @Scott8440 @HannaFar
+nms/ @karthiksubraveti @andreilee @HannaFar
CODEOWNERS @amarpad @electronjoe
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
deleted file mode 100644
index a1ba4e3fd4f1..000000000000
--- a/CONTRIBUTING.md
+++ /dev/null
@@ -1,10 +0,0 @@
-# Contributing to Magma
-We want to make contributing to this project as easy and transparent as
-possible.
-
-Please refer to the [Governance](https://github.com/magma/community)
-and [Contribution](https://github.com/magma/community/blob/main/CONTRIBUTING.md)
-model to get started.
-
-The [Wiki](https://github.com/magma/magma/wiki) outlines
-language specific guidelines.
diff --git a/README.md b/README.md
index 18f52acf9646..0d779c60f918 100644
--- a/README.md
+++ b/README.md
@@ -1,41 +1,65 @@
-# Magma
-
-[](https://circleci.com/gh/magma/magma)
+
+
+
+
+Connecting the Next Billion People
+
+
+
+
+
+
+
+
+
+
+
Magma is an open-source software platform that gives network operators an open, flexible and extendable mobile core network solution. Magma enables better connectivity by:
-* Allowing operators to offer cellular service without vendor lock-in with a modern, open source core network
-* Enabling operators to manage their networks more efficiently with more automation, less downtime, better predictability, and more agility to add new services and applications
-* Enabling federation between existing MNOs and new infrastructure providers for expanding rural infrastructure
-* Allowing operators who are constrained with licensed spectrum to add capacity and reach by using Wi-Fi and CBRS
+- Allowing operators to offer cellular service without vendor lock-in with a modern, open source core network
+- Enabling operators to manage their networks more efficiently with more automation, less downtime, better predictability, and more agility to add new services and applications
+- Enabling federation between existing MNOs and new infrastructure providers for expanding rural infrastructure
+- Allowing operators who are constrained with licensed spectrum to add capacity and reach by using Wi-Fi and CBRS
## Magma Architecture
The figure below shows the high-level Magma architecture. Magma is 3GPP generation (2G, 3G, 4G or upcoming 5G networks) and access network agnostic (cellular or WiFi). It can flexibly support a radio access network with minimal development and deployment effort.
-Magma has three major components:
+Magma has three major components
-* **Access Gateway:** The Access Gateway (AGW) provides network services and policy enforcement. In an LTE network, the AGW implements an evolved packet core (EPC), and a combination of an AAA and a PGW. It works with existing, unmodified commercial radio hardware.
+- **Access Gateway.** The Access Gateway (AGW) provides network services and policy enforcement. In an LTE network, the AGW implements an evolved packet core (EPC), and a combination of an AAA and a PGW. It works with existing, unmodified commercial radio hardware.
-* **Orchestrator:** Orchestrator is a cloud service that provides a simple and consistent way to configure and monitor the wireless network securely. The Orchestrator can be hosted on a public/private cloud. The metrics acquired through the platform allows you to see the analytics and traffic flows of the wireless users through the Magma web UI.
+- **Orchestrator.** Orchestrator is a cloud service that provides a simple and consistent way to configure and monitor the wireless network securely. The Orchestrator can be hosted on a public/private cloud. The metrics acquired through the platform allows you to see the analytics and traffic flows of the wireless users through the Magma web UI.
-* **Federation Gateway:** The Federation Gateway integrates the MNO core network with Magma by using standard 3GPP interfaces to existing MNO components. It acts as a proxy between the Magma AGW and the operator's network and facilitates core functions, such as authentication, data plans, policy enforcement, and charging to stay uniform between an existing MNO network and the expanded network with Magma.
+- **Federation Gateway.** The Federation Gateway integrates the MNO core network with Magma by using standard 3GPP interfaces to existing MNO components. It acts as a proxy between the Magma AGW and the operator's network and facilitates core functions, such as authentication, data plans, policy enforcement, and charging to stay uniform between an existing MNO network and the expanded network with Magma.

-## Usage Docs
-The documentation for developing and using Magma is available at: [https://docs.magmacore.org/docs/basics/introduction.html](https://docs.magmacore.org)
+## Documentation
+
+Magma's usage docs, and developer docs, are available at [https://docs.magmacore.org/docs/basics/introduction.html](https://docs.magmacore.org).
+
+## Join the Magma community
+
+See the [Community](https://www.magmacore.org/community/) page for entry points.
+
+Start by joining the community on Slack: [magmacore workspace](https://join.slack.com/t/magmacore/shared_invite/zt-g76zkofr-g6~jYiS3KRzC9qhAISUC2A).
+
+## Contributing
+
+Start with the project's contributing conventions
-## Join the Magma Community
+- [Contributing Conventions](https://docs.magmacore.org/docs/next/contributing/contribute_conventions)
+ for conventions on contributing to the project
-- Mailing lists:
- - Join [magma-dev](https://groups.google.com/forum/#!forum/magma-dev) for technical discussions
- - Join [magma-announce](https://groups.google.com/forum/#!forum/magma-announce) for announcements
-- Slack:
- - [magma\_dev](https://join.slack.com/t/magmacore/shared_invite/zt-g76zkofr-g6~jYiS3KRzC9qhAISUC2A) channel
+If you're new to the project, also consider reading
-See the [CONTRIBUTING](CONTRIBUTING.md) file for how to help out.
+- [Developer onboarding](https://docs.magmacore.org/docs/next/contributing/contribute_onboarding)
+ for onboarding to the project
+- [Development workflow](https://docs.magmacore.org/docs/next/contributing/contribute_workflow) for how to open a
+ pull request
## License
diff --git a/circleci/fabfile.py b/circleci/fabfile.py
index 7b4d37829022..b222ccb15b1d 100644
--- a/circleci/fabfile.py
+++ b/circleci/fabfile.py
@@ -324,15 +324,15 @@ def _deploy_lte_packages(repo: str, magma_root: str):
get('/tmp/packages.tar.gz', 'packages.tar.gz')
get('/tmp/packages.txt', 'packages.txt')
get('/tmp/magma_version', 'magma_version')
- get(f'{repo_name}/{magma_root}/lte/gateway/release/magma.lockfile',
- 'magma.lockfile')
+ get(f'{repo_name}/{magma_root}/lte/gateway/release/magma.lockfile.debian',
+ 'magma.lockfile.debian')
with open('magma_version') as f:
magma_version = f.readlines()[0].strip()
s3_path = f's3://magma-images/gateway/{magma_version}'
local(f'aws s3 cp packages.txt {s3_path}.deplist '
f'--acl bucket-owner-full-control')
- local(f'aws s3 cp magma.lockfile {s3_path}.lockfile '
+ local(f'aws s3 cp magma.lockfile.debian {s3_path}.lockfile.debian '
f'--acl bucket-owner-full-control')
local(f'aws s3 cp packages.tar.gz {s3_path}.deps.tar.gz '
f'--acl bucket-owner-full-control')
diff --git a/cwf/gateway/go.mod b/cwf/gateway/go.mod
index 2dca54b2982f..8d8647330c0c 100644
--- a/cwf/gateway/go.mod
+++ b/cwf/gateway/go.mod
@@ -40,7 +40,7 @@ require (
github.com/go-openapi/swag v0.19.5
github.com/go-redis/redis v6.15.5+incompatible
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
- github.com/golang/protobuf v1.4.3
+ github.com/golang/protobuf v1.5.2
github.com/onsi/ginkgo v1.14.0 // indirect
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.5.1
diff --git a/cwf/gateway/go.sum b/cwf/gateway/go.sum
index da3fd0ec118a..0f805d84c488 100644
--- a/cwf/gateway/go.sum
+++ b/cwf/gateway/go.sum
@@ -250,6 +250,8 @@ github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
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.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
@@ -577,6 +579,8 @@ github.com/wadey/gocovmerge v0.0.0-20160331181800-b5bfa59ec0ad/go.mod h1:Hy8o65+
github.com/warthog618/sms v0.3.0/go.mod h1:+bYZGeBxu003sxD5xhzsrIPBAjPBzTABsRTwSpd7ld4=
github.com/wmnsk/go-gtp v0.7.15/go.mod h1:v1psjZ7skpPSDegH23Amg9rNufs0BoXNM+GBtW5t58I=
github.com/wmnsk/go-gtp v0.7.17/go.mod h1:IQ5tTgk1EDaKLLAum2vzYheKX9JeRngM1fm9ohdXAac=
+github.com/wmnsk/go-gtp v0.7.19/go.mod h1:qdjTIBWIWjsNJdGs1EpmbcLjakUDPP7nRcEfKr2g1GQ=
+github.com/wmnsk/go-gtp v0.7.20/go.mod h1:qdjTIBWIWjsNJdGs1EpmbcLjakUDPP7nRcEfKr2g1GQ=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
@@ -768,6 +772,8 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
+google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
+google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/DATA-DOG/go-sqlmock.v1 v1.3.0 h1:FVCohIoYO7IJoDDVpV2pdq7SgrMH6wHnuTyrdrxJNoY=
gopkg.in/DATA-DOG/go-sqlmock.v1 v1.3.0/go.mod h1:OdE7CF6DbADk7lN8LIKRzRJTTZXIjtWgA5THM5lhBAw=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
diff --git a/docs/docusaurus/i18n/en.json b/docs/docusaurus/i18n/en.json
index 4ca0d07e2006..975f6b78940b 100644
--- a/docs/docusaurus/i18n/en.json
+++ b/docs/docusaurus/i18n/en.json
@@ -18,7 +18,7 @@
"title": "Codeowners Workflow"
},
"contributing/contribute_conventions": {
- "title": "Code Conventions"
+ "title": "Contributing Conventions"
},
"contributing/contribute_onboarding": {
"title": "Developer Onboarding"
@@ -82,6 +82,18 @@
"howtos/thanos": {
"title": "Thanos"
},
+ "howtos/troubleshooting/agw_unable_to_checkin": {
+ "title": "Access Gateway Unable to Check-in to Orchestrator"
+ },
+ "howtos/troubleshooting/generate_admin_operator_certificates": {
+ "title": "Generate and update admin_operator certificates"
+ },
+ "howtos/troubleshooting/update_certificates": {
+ "title": "Update rootCA and controller SSL certificates"
+ },
+ "howtos/troubleshooting/user_unable_to_attach": {
+ "title": "User is unable to attach to Magma"
+ },
"howtos/config_agw_bridged": {
"title": "AGW Bridged Mode"
},
@@ -331,6 +343,12 @@
"proposals/p011_victoriametrics": {
"title": "VictoriaMetrics as Magma's TSDB"
},
+ "proposals/p012_resource-tagging": {
+ "title": "proposals/p012_resource-tagging"
+ },
+ "proposals/p013_Ubuntu_upgrade": {
+ "title": "AGW Ubuntu upgrade"
+ },
"proposals/qos_enforcement": {
"title": "proposals/qos_enforcement"
},
diff --git a/docs/docusaurus/sidebars.json b/docs/docusaurus/sidebars.json
index 28995c820203..74d89712659e 100644
--- a/docs/docusaurus/sidebars.json
+++ b/docs/docusaurus/sidebars.json
@@ -46,6 +46,16 @@
"nms/alerts",
"nms/tips_and_tricks"
]
+ },
+ {
+ "type": "subcategory",
+ "label": "Troubleshooting",
+ "ids": [
+ "howtos/troubleshooting/agw_unable_to_checkin",
+ "howtos/troubleshooting/user_unable_to_attach",
+ "howtos/troubleshooting/update_certificates",
+ "howtos/troubleshooting/generate_admin_operator_certificates"
+ ]
}
],
"Architecture": [
diff --git a/docs/docusaurus/static/img/magma-logo-purple.svg b/docs/docusaurus/static/img/magma-logo-purple.svg
new file mode 100644
index 000000000000..da6209337c40
--- /dev/null
+++ b/docs/docusaurus/static/img/magma-logo-purple.svg
@@ -0,0 +1,135 @@
+
+image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/readmes/assets/lte/attach_flow.png b/docs/readmes/assets/lte/attach_flow.png
new file mode 100644
index 000000000000..3dab25531d8c
Binary files /dev/null and b/docs/readmes/assets/lte/attach_flow.png differ
diff --git a/docs/readmes/contributing/contribute_conventions.md b/docs/readmes/contributing/contribute_conventions.md
index b7427c7a8ccb..fd65f901b3cf 100644
--- a/docs/readmes/contributing/contribute_conventions.md
+++ b/docs/readmes/contributing/contribute_conventions.md
@@ -1,42 +1,90 @@
---
id: contribute_conventions
-title: Code Conventions
+title: Contributing Conventions
hide_title: true
---
-# Code Conventions
+# Contributing Conventions
-This document describes code conventions for the Magma project. The goal of this style guide is to
+This document describes contributing conventions for the Magma project. The goal of this style guide is to
- Steer contributors away from experienced landmines
- Align on coding styles in support of a uniform Magma codebase, with the aim to improve developer productivity and codebase approachability
## General
-Throughout the Magma codebase, the principal convention is the [boy scout rule](https://www.oreilly.com/library/view/97-things-every/9780596809515/ch08.html): leave it better than you found it. Consider the following conventions when adding a PR
-
-- Add tests for your changes
- - Tests should cover, at minimum, the mainline of the new feature. For reference, that usually ends up around 50-70% coverage.
- - Unit tests should default to being placed in the same directory as the files they're testing, except for the following
- - Python: directly-adjacent `tests` directory
- - C/C++: directly-adjacent `tests` directory
- - Integration tests should be placed as close to the code-under-test as possible
- - If you're not sure how to test a change, reach out on the community Slack workspace for input
-- Cleanup changes should be in separate PRs than functional changes
- - Exception: if the area of the codebase you're editing needs a cleanup PR, but you don't have bandwidth to add one, default to mimicking the surrounding code
-- Use [Go-style doc comments](https://golang.org/doc/effective_go#commentary), where the doc comment is prefixed by the name of the object being documented
+Follow these conventions when making changes to the Magma codebase.
+
+### Leave it better than you found it
+
+- The project's principal convention is the [boy scout rule](https://www.oreilly.com/library/view/97-things-every/9780596809515/ch08.html): leave it better than you found it
+
+### Add tests for your changes
+
+- Tests should cover, at minimum, the mainline of the new feature. For reference, that usually ends up around 50-70% coverage.
+- Unit tests should default to being placed in the same directory as the files they're testing, except for the following
+ - Python: directly-adjacent `tests` directory
+ - C/C++: directly-adjacent `tests` directory
+- Integration tests should be placed as close to the code-under-test as possible
+- If you're not sure how to test a change, reach out on the community Slack workspace for input
+
+### Separate cleanup PRs from functional changes
+
+- Keeps PRs small and understandable
+- Exception: if the area of the codebase you're editing needs a cleanup PR, but you don't have bandwidth to add one, default to mimicking the surrounding code
+
+### Scope component responsibilities
+
+- Functions, and components in general, should be narrowly scoped to a single, specific role
+- When writing a function over 100 lines long, consider extracting a helper functions out of the intermediate logical steps
+
+### Prefer immutability and idempotency
+
+- Prefer immutable state
+- When mutability is necessary, consider the following
+ - Prefer to set a component's state entirely in its constructor
+ - Mutate a component's state as close to construction-time as possible
+ - Perform mutations as high in the call chain as possible
+- Prefer side-effect-free functions
+ - When side-effects are necessary, move them as high in the call chain as possible
+
+### Prefer composition over inheritance
+
+- Avoid inheritance as a design pattern, in favor of composition and dependency injection
+- If complex logic begins bleeding into test case setup, consider pulling that logic into a dependency interface
+- Build a complex component as a composition of multiple simpler components with clear interfaces
+- Avoid non-trivial static functions: pull interfaces out of the static functions and inject them into depending components
+
+### Use simple constructors
+
+- Split complex logic and side-effect-inducing functionality out of the constructor and into an initialization method
+- If desired, can also use a static factory function to construct the component and call its initialization method
+
+### Comment with why, not what
+
+- Good code is self-documenting
+- Instead of defaulting to inline comments, focus on
+ - Concise and descriptive identifier names
+ - Intelligent types and pervasive typing information
+ - High-quality docstrings on functions, components, and top-level identifiers
- Avoid "topic sentence" comments
- E.g. "this block of code does X ... this block of code does Y", when there's no value-add other than summarizing the next few lines
- - Instead, code paragraphs should be skimmable. Also consider breaking dense code paragraphs out into private functions.
+ - Instead, code paragraphs should be skimmable
+ - Consider breaking dense code paragraphs out into private functions.
+- Save comments for code blocks that require non-obvious context, e.g. answering why an idiosyncratic or non-obvious decision was made
+
+### Style conventions
+
+- Use [Go-style doc comments](https://golang.org/doc/effective_go#commentary), where the doc comment is prefixed by the name of the object being documented
+- Use [Americanized spellings](https://en.wikipedia.org/wiki/Wikipedia:List_of_spelling_variants)
+ - marshaling, marshaled
+ - canceling, canceled, cancellation
- Prefer underscores over hyphens
- File, directory names
- YAML, JSON
- Exception: in certain parts of K8s, underscores are disallowed. In this case, hyphens are preferred, and translation between hyphens and underscores is acceptable.
- Omit trailing slash of directory paths, except where semantically meaningful
-- Don't terminate service names with `d`
-- Use [Americanized spellings](https://en.wikipedia.org/wiki/Wikipedia:List_of_spelling_variants)
- - marshaling, marshaled
- - canceling, canceled, cancellation
+- Don't terminate new service names with `d`
## Documentation
diff --git a/docs/readmes/contributing/contribute_onboarding.md b/docs/readmes/contributing/contribute_onboarding.md
index 540c590fb39b..c10b2f19c1fb 100644
--- a/docs/readmes/contributing/contribute_onboarding.md
+++ b/docs/readmes/contributing/contribute_onboarding.md
@@ -6,7 +6,7 @@ hide_title: true
# Developer Onboarding
-This document walks a new developer through the process of onboarding to Magma, specifically to the Orc8r subproject within the Magma project.
+This document walks a new developer through the process of onboarding to the Magma project.
## Project overview
@@ -14,7 +14,13 @@ Magma is an open-source software platform that gives network operators an open,
In more approachable terms, Magma is a collection of software that makes running things like a cellular network affordable and customizable. With Magma's current rate of growth, increasing stability and reliability of the platform are all huge wins.
-There are three main components in the Magma software platform: Access Gateway (AGW), Orc8r (Orc8r), and Federation Gateway (FeG). If you want to read more, see the [Magma intro docs](https://magma.github.io/magma/docs/next/basics/introduction.html).
+There are three main components in the Magma software platform: Access Gateway (AGW), Orchestrator (Orc8r), and Federation Gateway (FeG). If you want to read more, see the [Magma intro docs](https://magma.github.io/magma/docs/next/basics/introduction.html).
+
+### Access Gateway
+
+The AGW provides network services and policy enforcement. In an LTE network, the AGW implements an evolved packet core (EPC), and a combination of an AAA and a PGW. It works with existing, unmodified commercial radio hardware.
+
+More generally, the AGW defines datapath rules for connecting subscribers through to the Internet. It pulls configuration from Orc8r, sets datapath rules, manages charging and accounting, reports state and metrics to Orc8r, and more.
### Orchestrator
@@ -22,10 +28,6 @@ The Orc8r is a centralized controller for a set of networks. In [SDN](https://en
One of the functions of the Orc8r is to expose a management [REST API](https://restfulapi.net/). The REST API is defined as an [OpenAPI](https://swagger.io/solutions/getting-started-with-oas/) [specification](https://swagger.io/specification/) (aka [Swagger](https://swagger.io/blog/api-strategy/difference-between-swagger-and-openapi/) specification), and made available to operators over [mutually-authenticated](https://comodosslstore.com/blog/what-is-ssl-tls-client-authentication-how-does-it-work.html) HTTPS. The Orc8r also exposes a series of [gRPC](https://grpc.io/) services which gateways can call to report state, receive config updates, etc.
-### Access Gateway
-
-The AGW defines datapath rules for connecting subscribers through to the Internet. It pulls configuration from Orc8r, sets datapath rules, manages charging and accounting, reports state and metrics to Orc8r, and more.
-
### Federation Gateway
The FeG serves as the interface to existing operator cores, affording a modern, flexible interface on top of existing protocols and architectures.
@@ -96,8 +98,8 @@ Install Magma locally and get everything running.
1. Follow the [prerequisites guide](https://magma.github.io/magma/docs/next/basics/prerequisites) and install all development tools, up to but not including the "Build/Deploy Tooling" section
2. Run all Orc8r tests
- 1. Via Docker build script: `cd ${MAGMA_ROOT}/Orc8r/cloud/docker && ./build.py -t ; noti`
- 2. [Via IntelliJ](https://magma.github.io/magma/docs/next/Orc8r/development/testing_tips)
+ 1. Via Docker build script: `cd ${MAGMA_ROOT}/orc8r/cloud/docker && ./build.py -t ; noti`
+ 2. [Via IntelliJ](https://magma.github.io/magma/docs/next/orc8r/development/testing_tips)
3. Follow the [quick start guide](https://magma.github.io/magma/docs/next/basics/quick_start_guide) to get an AGW and Orc8r instance running on your dev machine
4. Visit the local [Swagger UI](https://swagger.io/tools/swagger-ui/) view of our REST API (URL is in @hcgatewood's Google Chrome bookmarks) and [list the set of managed networks](https://localhost:9443/apidocs/v1/#/Networks/get_networks) -- there should be one named "test"
- You will need to toggle a Google Chrome preference to [allow insecure localhost](https://superuser.com/questions/772762/how-can-i-disable-security-checks-for-localhost)
@@ -108,7 +110,7 @@ Note: remember to periodically call `docker system prune` to clear outdated Dock
If you haven't already, join our community Slack channel via the link from the [Community](https://www.magmacore.org/community/) page and say hello in `#general`. We can point you toward a good starter task. You can also use the [`good first issue` tag on our GitHub repo to search for good starter tasks](https://github.com/magma/magma/labels/good%20first%20issue).
-As you're working on your starter task, refer to [Development Workflow](./contribute_workflow.md) for guidance on how to author a pull request and [Code Conventions](./contribute_conventions.md) for Magma conventions. Once your pull request is approved and merged, you're now an official contributor to the Magma project!
+As you're working on your starter task, refer to [Development Workflow](./contribute_workflow.md) for guidance on how to author a pull request and [Contributing Conventions](./contribute_conventions.md) for Magma conventions. Once your pull request is approved and merged, you're now an official contributor to the Magma project!
### Next steps
diff --git a/docs/readmes/feg/docker.md b/docs/readmes/feg/docker.md
new file mode 100644
index 000000000000..b7cd35e82c52
--- /dev/null
+++ b/docs/readmes/feg/docker.md
@@ -0,0 +1,63 @@
+---
+id: docker_setup
+title: FeG Docker Setup
+hide_title: true
+---
+# FeG Docker Setup
+
+The FeG runs each service in its own Docker container.
+Production services are defined in `docker-compose.yml`.
+Development services are defined in `docker-compose.override.yml`.
+The development `test` service is used to run unit tests and regenerate Swagger/Protobuf code.
+The development `test` service can also be used to perform other development-related procedures.
+
+## Requirements
+
+To run the FeG with docker, both docker and docker compose must be installed.
+* Follow [these steps](https://docs.docker.com/install/) to install docker
+* Follow [these steps](https://docs.docker.com/compose/install/) to install docker compose
+
+NOTE: If you are running the FeG on Mac, you will need to increase the memory
+limit of the docker daemon to at least 4GB to build the images. Otherwise,
+when building the Go image, you may see an error message similar to this:
+`/usr/local/go/pkg/tool/linux_amd64/link: signal: killed`.
+
+The `rootCA.pem` certificate must be located in the `.cache/test_certs` folder,
+so that it can be mounted into the appropriate containers from there.
+
+## Development
+
+Follow these steps to run the FeG services:
+1. `cd magma/feg/gateway/docker`
+2. `docker-compose build`
+3. `docker-compose up -d`
+
+Each service should now be running in each of its containers.
+By default, both production and development services should be running.
+To place a shell into the test container, run the command:
+
+`docker-compose exec test /bin/bash`
+
+The test container contains the mounted source code and configuration settings.
+The mounted source code and configuration settings can be changed externally
+and the changes will be reflected inside the test container.
+Run the command `make precommit` in the container before submitting a patch.
+
+To make changes to currently running FeG services, the containers must be rebuilt and restarted:
+1. `docker-compose down`
+2. `docker-compose build`
+3. `docker-compose up -d`
+
+To manage the containers, the following commands are useful:
+* `docker-compose ps` (get status of each container)
+* `docker-compose logs -f` (tail logs of all containers)
+* `docker-compose logs -f ` (tail logs of a particular service)
+* `docker-compose down` (stop all services)
+
+## Publishing the images
+
+To push production images to a private docker registry, use the following script:
+```
+[/magma/feg/gateway/docker]$ ../../../orc8r/tools/docker/publish.sh -r -i gateway_python
+[/magma/feg/gateway/docker]$ ../../../orc8r/tools/docker/publish.sh -r -i gateway_go
+```
diff --git a/docs/readmes/feg/session_proxy.md b/docs/readmes/feg/session_proxy.md
new file mode 100644
index 000000000000..2274613409f1
--- /dev/null
+++ b/docs/readmes/feg/session_proxy.md
@@ -0,0 +1,49 @@
+# Session Proxy
+
+## Overview of Session Proxy
+session_proxy is a service from the FEG that interacts with PCRF and OCS.
+It's main function is to translate GRPC messages from sessiond into Diameter protocol back and forth.
+
+## Interfaces
+1. Session Manager (sessiond)
+Magma PCEF is implemented by Session Manager (or sessiond). Session Proxy receive the GRPC messages
+translates from sessiond and translates them into diameter messages for creation (CCR-I and CCA-I),
+update (CCR-U and CCA-U) and termination (CCR-T and CCA-T).
+
+2. PCRF (Gx)
+session_proxy implements Gx interface and will translate policy related calls into diameter AVPs to
+be sent to PCRF. It supports some events like monitoring tracking, time based rules,
+and PCRF initiated messages like reauthentication
+
+3. OCS (Gy)
+session_proxy implements Gy interface and will translate charging related calls into diameter AVPs to
+be sent to OCS. It supports charging reporting and OCS initiated messages like reauthentication
+
+4. PoicyDb
+session_proxy will get static rules and omnipresent rules from policyDb to inject
+them to the responses back to SessionD
+
+
+##Session Proxy Configuration
+Configuration of Session Proxy can be done through NMS or Swagger API. In both
+cases the configuration of Session Proxy is through Gx and Gy labels/tabs.
+
+
+## Magma PCRF-less configuration
+Omnipresent rules can be used as a way to achieve a PCRF-less (Gx) configuration while
+maintaining charging (Gy) capabilities. Omnipresent rules are configured on Orc8r and injected
+by session proxy to any subscriber that creates a new session. So if those omnipresent rules define a
+Rating Group (or charging key), that key will be used by to charge the user and will
+be communicated through Gy. Note that **all** subscribers will need to have that Rating Group
+configured on OCS so the reporting is tracked.
+
+###Configure Magma PCRF-less:
+- Create omnipresent rules:
+On NMS, create a static rule. In case you want to use charging (Gy) for that rule add a Rating Group
+Then check the box that says `omnipresent`. Once this is enable, any subscriber that attaches to the
+network will get that rule installed. Remember to check that subscriber on OCS too.
+
+- Disable Gx (optional):
+If there is not a PCRF to connect to, you can disable Gx so your session proxy doesn't try to connect to a
+non-existing PCRF. To do so go to swagger API `/feg/{network_id}/gateways/{gateway_id}`
+search for your Federated Gateway(using `feg network` and `feg gateway`) and modify `disableGx` under `Gx` key.
diff --git a/docs/readmes/howtos/troubleshooting/agw_unable_to_checkin.md b/docs/readmes/howtos/troubleshooting/agw_unable_to_checkin.md
new file mode 100644
index 000000000000..3c8e38533234
--- /dev/null
+++ b/docs/readmes/howtos/troubleshooting/agw_unable_to_checkin.md
@@ -0,0 +1,85 @@
+---
+id: agw_unable_to_checkin
+title: Access Gateway Unable to Check-in to Orchestrator
+hide_title: true
+---
+# Access Gateway Unable to Check-in to Orchestrator
+
+**Description:** After deploying AGW and Orchestrator, it is time to make AGW accessible from Orchestrator. After following github Magma AGW configuration [guide](https://magma.github.io/magma/docs/next/lte/config_agw), it was observed that AGW is not able to check-in to Orchestrator.
+
+**Environment:** AGW and Orc8r deployed.
+
+**Affected components:** AGW, Orchestrator
+
+**Triaging steps:**
+
+1. Diagnose AGW and Orchestrator setup with script checkin_cli.py. If the test is not successful, the script would provide potential root cause for a problem. A successful script will look like below:
+
+```
+AGW$ sudo checkin_cli.py
+
+1. -- Testing TCP connection to controller-staging.magma.etagecom.io:443 --
+2. -- Testing Certificate --
+3. -- Testing SSL --
+4. -- Creating direct cloud checkin --
+5. -- Creating proxy cloud checkin --
+```
+
+If the output is not successful, the script will recommend some steps to resolve the problem. After following the steps the problem has not been resolved, follow below steps.
+
+2. Make sure that the hostnames and ports specified in control_proxy.yml file in AGW are properly set.
+Sample control_proxy.yml file
+
+```
+cloud_address: controller.yourdomain.com
+cloud_port: 443
+bootstrap_address: bootstrapper-controller.yourdomain.com
+bootstrap_port: 443
+
+rootca_cert: /var/opt/magma/tmp/certs/rootCA.pem
+```
+
+3. Verify the certificate rootCA.pem is in the correct location defined in rootca_cert (specified in control_proxy.yml)
+
+4. Make sure the certificates have not expired.
+ Note: To obtain certificate information you can use `openSSL x509 -in certificate -noout -text`
+ - In AGW: rootCA.pem
+ - In Orc8r: rootCA.pem, controller.cert
+
+5. Verify the domain is consistent across AGW and Orc8r and the CN matches with the domain
+ - CN in rootCA.pem AGW
+ - CN in Orc8r for root and controller certificates.
+ - The domain in `main.tf`
+
+6. Verify connectivity between AGW and Orc8r. Choose the port and domain obtained in `control_proxy.yml`. You can use telnet, example below:
+ `telnet bootstrapper-controller.yourdomain.com 443`
+
+
+7. Verify the DNS resolution of the bootstrap and controller domain.
+ - In AGW: You can ping or telnet to your bootstrap and controller domain from AGW to verify which AWS address is being resolved.
+ - In Orc8r: Verify which external-IP your cluster is assigned. You can use the command: `kubectl get services`
+
+ The address resolved in AGW should be the same defined in Orc8r. If not, verify your DNS resolution.
+
+
+8. Verify that there are no errors in AGW magmad service.
+
+ `AGW$ sudo tail -f /var/log/syslog | grep -i "magmad"`
+
+
+
+9. From Orchestrator, get all pods and find pod orc8r-controller-*
+
+```
+kubectl -n magma get pods
+kubectl -n magma logs -f
+```
+
+First command will list all pods and next command can be used to check logs of a particular pod. Check if there is any problematic log for the related pod.
+
+10. Try restarting magmad services.
+```
+AGW$ sudo service magma@magmad restart
+```
+
+11. If issue still persists, please file github issues or ask in our support channels https://www.magmacore.org/community/
diff --git a/docs/readmes/howtos/troubleshooting/generate_admin_operator_certificates.md b/docs/readmes/howtos/troubleshooting/generate_admin_operator_certificates.md
new file mode 100644
index 000000000000..b5e37c878acc
--- /dev/null
+++ b/docs/readmes/howtos/troubleshooting/generate_admin_operator_certificates.md
@@ -0,0 +1,59 @@
+---
+id: generate_admin_operator_certificates
+title: Generate and update admin_operator certificates
+hide_title: true
+---
+# Generate and update admin_operator certificates
+
+**Description:** NMS is unable to communicate with the controller or API access is no longer functional due to certificate used for the TLS handshake has expired. Below guide provide the steps to generate new admin_operator certificates and upload it to the NMS k8s pod for NMS access and to the browser for the API access.
+
+**Environment:** Orchestrator, NMS in Kubernetes/AWS
+
+**Affected components:** Orchestrator, NMS
+
+**Configuration steps:**
+
+
+1. Log on to a host that has kubectl access to your orc8r cluster.
+2. Access the shell on your controller pod.
+
+`export CNTLR_POD=$(kubectl -n orc8r get pod -l app.kubernetes.io/component=controller -o jsonpath='{.items[0].metadata.name}')`
+
+`kubectl exec -it ${CNTLR_POD} bash`
+
+3. Run the following commands inside the k8s controller pod to generate a new `admin_operator` cert. The `admin_operator.pfx` file is only for API access for the user to get to the browser.
+
+```
+# The following commands are to be run inside the pod
+(pod)$ cd /var/opt/magma/bin
+(pod)$ envdir /var/opt/magma/envdir ./accessc add-admin -cert admin_operator admin_operator
+(pod)$ openssl pkcs12 -export -out admin_operator.pfx -inkey admin_operator.key.pem -in admin_operator.pem
+
+Enter Export Password:
+Verifying - Enter Export Password:
+```
+
+4. Copy the k8s certs from the controller k8s pod to the local directoy where all your secrets are held.
+
+NOTE: Make sure the location where these certificates are being copied to is the same location which is referenced in the main.tf file for the seed_certs_dir variable.
+```
+cd ~/secrets/certs
+for certfile in admin_operator.pem admin_operator.key.pem admin_operator.pfx
+do
+ kubectl cp orc8r/${CNTLR_POD}:/var/opt/magma/bin/${certfile} ./${certfile}
+done
+```
+5. At this point the new certs have been generated, you can use the `admin_operator.pfx` to validate that you can reach the API endpoint. However, they still need to be applied to the k8s secrets manager so that they can be mounted in the nms pod. To do this, initialize your terraform first using terraform init -upgrade.
+
+6. To replace certs, we have to first taint the secrets in terraform so that terraform knows to destroy those secrets first and then re-apply them. Taint them using terraform `taint module.orc8r-app.null_resource.orc8r_seed_secrets`
+
+7. Once the secrets have been tainted, you can then go ahead and apply the new secrets by running `terraform apply -target=module.orc8rapp.null_resource.orc8r_seed_secrets` followed by `terraform apply`
+
+NOTE: `terraform apply` command outputs the “plan” of what it intends to add,destroy,modify. Please scrutinize this output before typing “yes” on the confirm prompt. If there are any changes that are not consistent with your expectations, please cancel the run. You can specifically target the secrets portion by doing `terraform apply -target=module.`
+
+8. Once the terraform apply succeeds, the NMS will not automatically get the new certificates until we destroy the existing pod and force the replication controller to instantiate another instance of the pod. To do this, run the following commands:
+```
+export NMS_POD=$(kubectl -n orc8r get pod -l app.kubernetes.io/component=magmalte -o jsonpath='{.items[0].metadata.name}')
+kubectl -n orc8r delete pod NMS_POD
+```
+9. Once the pod reinitializes, it should have the latest admin_operator certs and be able to re-establish communication with the controller.
diff --git a/docs/readmes/howtos/troubleshooting/update_certificates.md b/docs/readmes/howtos/troubleshooting/update_certificates.md
new file mode 100644
index 000000000000..901a77dd960a
--- /dev/null
+++ b/docs/readmes/howtos/troubleshooting/update_certificates.md
@@ -0,0 +1,110 @@
+---
+id: update_certificates
+title: Update rootCA and controller SSL certificates
+hide_title: true
+---
+# Update rootCA and controller SSL certificates
+
+**Description:** This document describes the steps to update certificates `controller.crt`, `controller.key`, `rootCA.pem` and `rootCA.key` on Orchestrator/Access Gateway. These steps should follow on an Orc8r already deployed where is required to extend the expiration date of the certificates. This shouldn't be use for change of CN.
+
+**Environment:** Orchestrator in Kubernetes/AWS
+
+**Affected components:** AGW, Orchestrator
+
+**Configuration steps on Orchestrator:**
+
+
+1. Create a new rootCA.pem, rootCA.key, controller.crt and controller.key.
+
+ - The public SSL certificate for your Orchestrator domain,
+ with `CN=*.yourdomain.com`. This can be an SSL certificate chain, but it must be
+ in one file
+
+ - The private key which corresponds to the above SSL certificate
+
+ - The root CA certificate which verifies your SSL certificate
+
+ If you aren't worried about a browser warning, you can generate self-signed
+ versions of these certs
+
+ ```bash
+ ${MAGMA_ROOT}/orc8r/cloud/deploy/scripts/self_sign_certs.sh yourdomain.com
+ ```
+
+ Alternatively, if you already have these certs, rename and move them as follows
+
+ - Rename your public SSL certificate to `controller.crt`
+
+ - Rename your SSL certificate's private key to `controller.key`
+
+ - Rename your SSL certificate's root CA certificate to `rootCA.pem`
+
+
+2. Move these certificates into `~/secrets/certs`.
+
+3. Other certificates `bootstrapper.key`, `certifier.key`, `certifier.pem`, `fluentd.key`, `fluentd.pem`, `admin_operator.key.pem,` `admin_operator.pem` and `admin_operator.pfx` **don't** need to change and you can copy into the folder `~/secrets/certs`. The certs directory should now look like this
+
+```bash
+$ ls -1 ~/secrets/certs/
+
+admin_operator.key.pem
+admin_operator.pem
+admin_operator.pfx
+bootstrapper.key
+certifier.key
+certifier.pem
+controller.crt
+controller.key
+fluentd.key
+fluentd.pem
+rootCA.pem
+rootCA.key
+```
+
+
+4. Opt to upgrade modules and plugins as part of their respective installation steps.
+
+`terraform init –upgrade`
+
+5. Run the following commands:
+
+`$ terraform taint module.orc8r-app.null_resource.orc8r_seed_secrets`
+
+`$ terraform apply -target=module.orc8rapp.null_resource.orc8r_seed_secrets`
+
+`$ terraform apply`
+
+
+NOTE: `terraform apply` command outputs the “plan” of what it intends to add,destroy,modify. Please scrutinize this output before typing “yes” on the confirm prompt. If there are any changes that are not consistent with your expectations, please cancel the run. You can specifically target the secrets portion by doing `terraform apply -target=module.`
+
+6. You can remove the secrets folder from your local disk. But make sure you have a copy of the `rootCA.key`
+
+7. Kill Controllers and Proxy pods one by one.
+
+`kubectl delete pods `
+
+**Configuration steps on Access Gateway:**
+
+1. Update the new `rootCA.pem` in `/var/opt/magma/tmp/certs/rootCA.pem`
+
+2. Restart magmad service
+
+`AGW$ sudo service magma@magmad restart`
+
+3. You can validate the connection between your AGW and Orchestrator:
+
+```bash
+AGW$ journalctl -u magma@magmad -f
+# Look for the following logs
+# INFO:root:Checkin Successful!
+# INFO:root:[SyncRPC] Got heartBeat from cloud
+# INFO:root:Processing config update gateway_id
+
+AGW$ sudo checkin_cli.py
+
+1. -- Testing TCP connection to controller-staging.magma.etagecom.io:443 --
+2. -- Testing Certificate --
+3. -- Testing SSL --
+4. -- Creating direct cloud checkin --
+5. -- Creating proxy cloud checkin --
+```
diff --git a/docs/readmes/howtos/troubleshooting/user_unable_to_attach.md b/docs/readmes/howtos/troubleshooting/user_unable_to_attach.md
new file mode 100644
index 000000000000..9f143d7a95e8
--- /dev/null
+++ b/docs/readmes/howtos/troubleshooting/user_unable_to_attach.md
@@ -0,0 +1,91 @@
+---
+id: user_unable_to_attach
+title: User is unable to attach to Magma
+hide_title: true
+---
+# User is unable to attach to Magma
+
+**Description:** This document describe the steps triage issues when a user is unable to attach to the network, AGW is rejecting the attach request.
+
+**Environment:** AGW and Orc8r deployed.
+
+**Affected components:** AGW, Orchestrator
+
+**Prerequisites**:
+
+- APN configuration has been done in Orc8r
+- AGW has been successfully registered in Orc8r
+- User has been registered in Orc8r with the correct parameters( Authentication and APN)
+- eNB has been successfully integrated with AGW
+
+
+**Triaging steps**:
+
+1. Run the command sudo mobility_cli.py get_subscriber_table, the output will show the list of subscribers(by IMSI) that are currently attached to the network. If the user is showing in the list, it means the attach request was successfully completed. If the IMSI is not showing there, proceed with the next step
+2. Verify in the pcap trace or NMS logs the reason of attach reject.
+ a. To obtain a pcap trace in AGW you can run the following command `sudo tcpdump -i any sctp -w `
+ b. To verify the logs in NMS you can go in NMS to Equipment->Select the AGW-> Logs->Search logs
+
+
+The attach request flow should follow below signal flow, where sctpd, mme, subscriberdb, mobilityd and sessiond are used services in the AGW:
+
+
+
+
+Below you will find possible causes of why the Attach Request could be rejected by AGW.
+
+
+**Causes related to invalid messages or Unknown messages**
+
+UE may include in the Attach Request a parameter Magma doesn’t support. Magma will reject the request with the following cause:
+
+```
+SEMANTICALLY_INCORRECT 95
+INVALID_MANDATORY_INFO 96
+MESSAGE_TYPE_NOT_IMPLEMENTED 97
+MESSAGE_TYPE_NOT_COMPATIBLE 98
+IE_NOT_IMPLEMENTED 99
+CONDITIONAL_IE_ERROR 100
+MESSAGE_NOT_COMPATIBLE 101
+PROTOCOL_ERROR 111
+```
+
+Suggested Solution:
+
+1. Identify which parameter the UE is sending in the Attach Request and compare with the ones Magma support. You can find which parameters magma is currently supported from the code. https://github.com/magma/magma/blob/master/lte/gateway/c/oai/tasks/nas/emm/msg/AttachRequest.c
+
+ Note: Make sure to select the branch you are currently have in your network(v1.1, v1.2, v1.3 , etc)
+
+2. Once you identify the parameter, verify with the UE/CPE vendor if you can disable it. If you can't disable, file a feature request.
+
+
+**Misconfiguration of APN**
+
+Using the pcap trace, verify the APN configured in NMS/Orc8r matches the APN sent by UE.
+- You will find the APN sent by UE in the “PDN connectivity request”( Attach Request) or in the “ESM information transfer”
+- Make sure the APN matches the one configured in Orc8r for this user
+
+
+
+**Cause related to subscription options**
+If the user is not correctly provisioned in the NMS/Orc8r, the attach request will be rejected with the following causes:
+
+```
+EMM_CAUSE_IMEI_NOT_ACCEPTED 5
+EMM_CAUSE_EPS_NOT_ALLOWED 7
+EMM_CAUSE_BOTH_NOT_ALLOWED 8
+EMM_CAUSE_PLMN_NOT_ALLOWED 11
+EMM_CAUSE_TA_NOT_ALLOWED 12
+EMM_CAUSE_ROAMING_NOT_ALLOWED 13
+EMM_CAUSE_EPS_NOT_ALLOWED_IN_PLMN 14
+EMM_CAUSE_NO_SUITABLE_CELLS 15
+EMM_CAUSE_CSG_NOT_AUTHORIZED 25
+EMM_CAUSE_NOT_AUTHORIZED_IN_PLMN 35
+EMM_CAUSE_NO_EPS_BEARER_CTX_ACTIVE 40
+```
+
+Suggested Solution:
+
+1. Double check with the Auth Key and OPC are correctly set for this user
+2. Verify the Auth Key and OPC values with the SIM vendor
+3. If issue still persists, please file github issues or ask in our support channels https://www.magmacore.org/community/
diff --git a/docs/readmes/lte/debug_dp_probe.md b/docs/readmes/lte/debug_dp_probe.md
index 98eb8540e43c..958e001be101 100644
--- a/docs/readmes/lte/debug_dp_probe.md
+++ b/docs/readmes/lte/debug_dp_probe.md
@@ -12,11 +12,16 @@ The datapath probe CLI helps an operator to probe the Datapath to the UE.
```sh
# On your GW host, run the following command
-$ dp_probe_cli.py -i
-$ dp_probe_cli.py -i 1010000051011
-IMSI: 1010000051011, IP: 192.168.128.15
-Running: sudo ovs-appctl ofproto/trace gtp_br0 tcp,in_port=local,ip_dst=192.168.128.15,ip_src=8.8.8.8,tcp_src=80,tcp_dst=3372
-Datapath Actions: set(tunnel(tun_id=0x1000308,dst=10.0.2.240,ttl=64,tp_dst=2152,flags(df|key))),pop_eth,2
+$ dp_probe_cli.py -i --direction
+$ dp_probe_cli.py -i 1010000051013 --direction DL
+IMSI: 1010000051013, IP: 192.168.128.13
+Running: sudo ovs-appctl ofproto/trace gtp_br0 tcp,in_port=local,ip_dst=192.168.128.13,ip_src=8.8.8.8,tcp_src=80,tcp_dst=3372
+Datapath Actions: set(tunnel(tun_id=0x1000008,dst=10.0.2.241,ttl=64,tp_dst=2152,flags(df|key))),pop_eth,2
+
+dp_probe_cli.py -i 1010000051013 --direction UL
+IMSI: 1010000051013, IP: 192.168.128.13
+Running: sudo ovs-appctl ofproto/trace gtp_br0 tcp,in_port=4,tun_id=0x2,ip_dst=8.8.8.8,ip_src=192.168.128.13,tcp_src=3372,tcp_dst=80
+Datapath Actions: set(eth(src=02:00:00:00:00:01,dst=92:9d:a2:1f:ea:44)),1
# You can also supply the followin options
# -I
@@ -24,15 +29,15 @@ Datapath Actions: set(tunnel(tun_id=0x1000308,dst=10.0.2.240,ttl=64,tp_dst=2152,
# -UP
# -p
-$ dp_probe_cli.py -i 1010000051016 -I 4.2.2.2 -p tcp -P 8080 -UP 3172
-IMSI: 1010000051016, IP: 192.168.128.14
-Running: sudo ovs-appctl ofproto/trace gtp_br0 tcp,in_port=local,ip_dst=192.168.128.14,ip_src=4.2.2.2,tcp_src=8080,tcp_dst=3172
-Datapath Actions: set(tunnel(tun_id=0x1000208,dst=10.0.2.240,ttl=64,tp_dst=2152,flags(df|key))),pop_eth,2
+dp_probe_cli.py -i 1010000051013 --direction UL -p tcp -I 4.2.2.2 -P 8080 -UP 3172
+IMSI: 1010000051013, IP: 192.168.128.13
+Running: sudo ovs-appctl ofproto/trace gtp_br0 tcp,in_port=4,tun_id=0x2,ip_dst=4.2.2.2,ip_src=192.168.128.13,tcp_src=3172,tcp_dst=8080
+Datapath Actions: set(eth(src=02:00:00:00:00:01,dst=92:9d:a2:1f:ea:44)),1
```
## What is this command doing?
-This command is a wrapper around *ovs-appctl ofproto/trace* which simulates the Datapath of the packet.
+This command is a wrapper around *ovs-appctl ofproto/trace* which simulates the Datapath of the packet based on the direction specified in the command. 'DL' - Incoming Packet, 'UL' - Outgoing packet.
## How to read the output?
diff --git a/docs/readmes/proposals/README.md b/docs/readmes/proposals/README.md
index 2543a57e13f9..5beb8429e823 100644
--- a/docs/readmes/proposals/README.md
+++ b/docs/readmes/proposals/README.md
@@ -96,7 +96,7 @@ document.
the directory and `short-name` is a short name (a few dash-separated words
at most).
Follow the Magma Github contribution process from the
- [Magma Contributing Wiki](https://github.com/magma/magma/wiki/Contributing).
+ [Magma Contributing Conventions](https://docs.magmacore.org/docs/next/contributing/contribute_conventions).
- The design doc should follow [the template](TEMPLATE.md).
diff --git a/docs/readmes/proposals/p013_Ubuntu_upgrade.md b/docs/readmes/proposals/p013_Ubuntu_upgrade.md
new file mode 100644
index 000000000000..9a32d675ba89
--- /dev/null
+++ b/docs/readmes/proposals/p013_Ubuntu_upgrade.md
@@ -0,0 +1,91 @@
+---
+id: p013_Ubuntu_upgrade
+title: AGW Ubuntu upgrade
+hide_title: true
+---
+
+# Overview
+
+*Status: Accepted*\
+*Author: @pshelar*\
+*Last Updated: 03/15*\
+*Targeted Release: 1.5*\
+*Feedback requested from: @arunuke*
+
+This document cover AGW ubuntu upgrade path
+
+## Goal
+Add support for Ubuntu based AGW.
+
+## Introduction
+
+There are multiple reasons to update base OS from current Debian to ubuntu distribution
+
+1. Python 3.5 is EOL on September 13th, 2020. Current Debian does not support the latest python release. pip 21.0
+ dropped support for Python 3.5 in January 2021.
+2. Newer kernel is required for enabling next generation datapath performance.
+3. Orc8r is already on Ubuntu. This would converge the magma platform on ubuntu distribution
+4. With newer distribution we can relax AGW kernel dependency using *DKMS packages for OVS kernel module*
+
+## Deployment scenarios for 1.5
+
+### *Fresh install on Ubuntu:*
+
+This is going to be default deployment OS for AGW from 1.5 onwards. Using ubuntu base OS for AGW 1.5 would also result
+in smoother AGW updates for future releases.
+
+### *Debian based AGW 1.4 to Debian based AGW 1.5:*
+
+Current production deployment can use current Debian upgrade path for upgrading magma from 1.4 to 1.5. Existing workflow
+remains same.
+
+### *Debian based AGW 1.4 to Ubuntu based AGW 1.5:*
+
+This deployment involves two steps first, upgrading underlying OS. OS upgrade can be performed either
+inplace upgrade or re-install of Ubuntu OS. Second step installing AGW packages.
+There is separate section below to discuss it in details.
+
+## Debian depreciation:
+
+Debian support will be deprecated on AGW 1.5. Default OS distribution for magma is going to be ubuntu. There would be
+support for Debian based deployment.
+This is subject to change depending on stability of ubuntu support for AGW 1.5.
+
+## Drop Debian support:
+
+Debian OS support would be dropped in AGW 1.6
+
+## Extended AGW 1.5 release cycle:
+
+To ease urgency of ubuntu upgrade, magma community could provide extra minor releases for 1.5. This way existing
+Debian based production deployment can continue to use debian based AGW and receive bug fixes for 1.5 release.
+
+## Debian to ubuntu upgrade solutions:
+
+### *Zero downtime:*
+
+1. Setup HA pair for AGW, either on-premises or on cloud, there is separate HA document for details.
+2. Fail-over all UEs to the new standby AGW.
+3. Follow steps in "Upgrade with single AGW node".
+4. All UEs would fallback to updated AGW 1.5.
+5. At this point the stand-by AGW can be removed.
+
+### *Upgrade with single AGW node:*
+
+This type of deployment results in downtime.
+
+1. Bring down AGW services
+2. Update base OS on AGW from Debian to ubuntu
+3. Deploy AGW 1.5
+4. Configure AGW
+5. Start AGW services
+
+## Major changes for Ubuntu upgrade.
+1. Update Python based services to Python 3.8
+2. Update OVS binaries from 2.8 to 2.14
+3. Use OVS DKMS kernel module package for GTP tunneling to support range of kernels, as of now it supports 4.9.214,
+ 4.14.171, 4.19.110, 5.4.50 and 5.6.19
+4. Add packaging scripts for Ubuntu
+5. Update magma artifactory to host packages for Ubuntu
+6. Add deployment script to deploy AGW on Ubuntu
+7. Add CI pipeline for Ubuntu based AGW
diff --git a/feg/cloud/go/protos/s8_proxy.pb.go b/feg/cloud/go/protos/s8_proxy.pb.go
index 906cfae96067..b07fb0be41c6 100644
--- a/feg/cloud/go/protos/s8_proxy.pb.go
+++ b/feg/cloud/go/protos/s8_proxy.pb.go
@@ -452,8 +452,9 @@ func (m *ServingNetwork) GetMnc() string {
type BearerContext struct {
Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
UserPlaneFteid *Fteid `protobuf:"bytes,2,opt,name=user_plane_fteid,json=userPlaneFteid,proto3" json:"user_plane_fteid,omitempty"`
- Qos *QosInformation `protobuf:"bytes,3,opt,name=qos,proto3" json:"qos,omitempty"`
- ChargingId uint32 `protobuf:"varint,4,opt,name=charging_id,json=chargingId,proto3" json:"charging_id,omitempty"`
+ ValidQos bool `protobuf:"varint,3,opt,name=valid_qos,json=validQos,proto3" json:"valid_qos,omitempty"`
+ Qos *QosInformation `protobuf:"bytes,4,opt,name=qos,proto3" json:"qos,omitempty"`
+ ChargingId uint32 `protobuf:"varint,5,opt,name=charging_id,json=chargingId,proto3" json:"charging_id,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@@ -498,6 +499,13 @@ func (m *BearerContext) GetUserPlaneFteid() *Fteid {
return nil
}
+func (m *BearerContext) GetValidQos() bool {
+ if m != nil {
+ return m.ValidQos
+ }
+ return false
+}
+
func (m *BearerContext) GetQos() *QosInformation {
if m != nil {
return m.Qos
@@ -1149,95 +1157,96 @@ func init() {
func init() { proto.RegisterFile("feg/protos/s8_proxy.proto", fileDescriptor_8a775e17ac280154) }
var fileDescriptor_8a775e17ac280154 = []byte{
- // 1402 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0xdd, 0x6e, 0xdb, 0x36,
- 0x14, 0x8e, 0xfc, 0x13, 0xdb, 0x27, 0x91, 0xa3, 0xb2, 0x59, 0xa3, 0xfe, 0x00, 0x4d, 0xd5, 0x75,
- 0xcd, 0x3a, 0x2c, 0xc9, 0xd2, 0x20, 0xe8, 0x06, 0x14, 0x9b, 0x93, 0xb8, 0x5d, 0x80, 0xd4, 0xf3,
- 0x68, 0x27, 0x03, 0x7a, 0x23, 0xd0, 0x14, 0xa3, 0x12, 0x93, 0x25, 0x85, 0x94, 0x93, 0x66, 0xc0,
- 0x80, 0xdd, 0x0e, 0xd8, 0xcd, 0x1e, 0x63, 0x97, 0xbb, 0xd9, 0x33, 0xed, 0x6e, 0xaf, 0x30, 0x90,
- 0xa2, 0x1d, 0x39, 0x99, 0xb1, 0x16, 0xe8, 0x95, 0x0f, 0xbf, 0xf3, 0x91, 0x3a, 0x3c, 0xfc, 0x0e,
- 0x0f, 0x0d, 0xb7, 0x4f, 0x58, 0xb8, 0x91, 0x8a, 0x24, 0x4b, 0xe4, 0x86, 0x7c, 0xe6, 0xa7, 0x22,
- 0x79, 0x7b, 0xb1, 0xae, 0xc7, 0xa8, 0x31, 0x24, 0xe1, 0x90, 0xac, 0x9f, 0xb0, 0xd0, 0xfb, 0xa7,
- 0x0a, 0x2b, 0x7b, 0x82, 0x91, 0x8c, 0xf5, 0x98, 0x94, 0x3c, 0x89, 0x31, 0x3b, 0x1d, 0x31, 0x99,
- 0x75, 0xc3, 0x73, 0x74, 0x07, 0xea, 0x69, 0x78, 0xde, 0x0a, 0x02, 0x21, 0x5d, 0x6b, 0xd5, 0x5a,
- 0x6b, 0xe0, 0xc9, 0x18, 0x21, 0xa8, 0xf0, 0xa1, 0xe4, 0x6e, 0x49, 0xe3, 0xda, 0x46, 0xb7, 0x60,
- 0x7e, 0x28, 0xb9, 0x0c, 0x62, 0xb7, 0xac, 0x51, 0x33, 0x42, 0x0e, 0x94, 0x87, 0x8c, 0xbb, 0x15,
- 0x0d, 0x2a, 0x13, 0xed, 0xc2, 0x92, 0x64, 0xe2, 0x8c, 0xc7, 0xa1, 0x1f, 0xb3, 0xec, 0x3c, 0x11,
- 0x3f, 0xba, 0xd5, 0x55, 0x6b, 0x6d, 0x61, 0xeb, 0xf6, 0xfa, 0x24, 0xb4, 0xf5, 0x5e, 0xce, 0xe8,
- 0xe4, 0x04, 0xdc, 0x94, 0x53, 0x63, 0xb4, 0x0d, 0xe5, 0x51, 0xc4, 0xdd, 0x79, 0x3d, 0xcf, 0x2b,
- 0xcc, 0x3b, 0x92, 0x4c, 0x1c, 0x26, 0x94, 0x64, 0x3c, 0x89, 0x0f, 0xe2, 0x93, 0x44, 0x0c, 0xb5,
- 0x89, 0x15, 0x1d, 0x7d, 0x0e, 0x75, 0x41, 0x32, 0x3f, 0xbb, 0x48, 0x99, 0x5b, 0x5b, 0xb5, 0xd6,
- 0x9a, 0x5b, 0xa8, 0x30, 0x15, 0xb7, 0xfa, 0xfd, 0x8b, 0x94, 0xe1, 0x9a, 0x20, 0x99, 0x32, 0x14,
- 0x3d, 0x0d, 0xe2, 0x9c, 0x5e, 0xbf, 0x46, 0xef, 0xee, 0x77, 0x72, 0x7a, 0x1a, 0xc4, 0x9a, 0xfe,
- 0x05, 0x94, 0x53, 0x42, 0xdc, 0x86, 0x8e, 0xe9, 0x7e, 0x91, 0x19, 0xc4, 0x2a, 0x6f, 0x4c, 0xca,
- 0x56, 0x14, 0x99, 0xd8, 0xb0, 0xe2, 0xaa, 0xe4, 0x90, 0x34, 0x76, 0x21, 0x4f, 0x0e, 0x49, 0x63,
- 0xf4, 0x10, 0x2a, 0x64, 0x38, 0x10, 0xee, 0x82, 0x5e, 0x65, 0xa9, 0xb0, 0x4a, 0x6b, 0x38, 0x10,
- 0x58, 0x3b, 0xd1, 0x1e, 0x34, 0x25, 0x8b, 0x18, 0x55, 0x0b, 0xf9, 0xc3, 0x24, 0x60, 0xee, 0xa2,
- 0x0e, 0xef, 0xde, 0x54, 0x02, 0x0d, 0xe1, 0x55, 0x12, 0x30, 0x1d, 0xa8, 0x2d, 0x8b, 0x10, 0xfa,
- 0x1a, 0x9a, 0x03, 0x46, 0x04, 0x13, 0x3e, 0x4d, 0xe2, 0x8c, 0xbd, 0xcd, 0x5c, 0x5b, 0x7f, 0xd3,
- 0x2d, 0x2c, 0xb2, 0xab, 0x09, 0x7b, 0xb9, 0x1f, 0xdb, 0x83, 0xe2, 0x10, 0xdd, 0x03, 0xa0, 0x3e,
- 0x09, 0xcf, 0xfd, 0x8c, 0xf1, 0xc0, 0x6d, 0xae, 0x5a, 0x6b, 0x36, 0xae, 0xd3, 0x56, 0x78, 0xde,
- 0x67, 0x3c, 0x40, 0x8f, 0x61, 0x89, 0xc7, 0x01, 0xcf, 0x77, 0xeb, 0x9f, 0x44, 0x24, 0x74, 0x97,
- 0x56, 0xad, 0xb5, 0x45, 0xdc, 0xbc, 0x84, 0x5f, 0x44, 0x24, 0x44, 0x5f, 0x82, 0x4b, 0xdf, 0x10,
- 0x11, 0x2a, 0x3d, 0x28, 0x83, 0xd0, 0x8c, 0x09, 0x2e, 0x33, 0x4e, 0xa5, 0xeb, 0xe8, 0xc4, 0xac,
- 0x8c, 0xfd, 0x7b, 0xd3, 0x6e, 0xb4, 0x09, 0x8d, 0x8c, 0x0f, 0x99, 0xff, 0x53, 0x12, 0x33, 0xf7,
- 0x86, 0x8e, 0xfe, 0x66, 0x21, 0xfa, 0x3e, 0x1f, 0xb2, 0xd7, 0x49, 0xcc, 0x70, 0x3d, 0x33, 0x96,
- 0xf7, 0xa7, 0x05, 0x2b, 0x33, 0x24, 0xa2, 0x0e, 0x23, 0x22, 0x54, 0x8b, 0xdd, 0xc6, 0xca, 0x44,
- 0x4d, 0x28, 0xd1, 0x5c, 0xe5, 0x36, 0x2e, 0x51, 0xae, 0x18, 0x92, 0x50, 0x2d, 0x70, 0x1b, 0x2b,
- 0x53, 0x21, 0x82, 0x50, 0xad, 0x6e, 0x1b, 0x2b, 0x53, 0x21, 0x19, 0xa1, 0x5a, 0xd1, 0x36, 0x56,
- 0xa6, 0x42, 0x18, 0xcd, 0xb5, 0x6a, 0x63, 0x65, 0xa2, 0x65, 0xa8, 0xbe, 0x62, 0x9d, 0x01, 0xd7,
- 0x22, 0xb4, 0x71, 0x3e, 0x50, 0x15, 0xd4, 0xce, 0xe1, 0xba, 0x86, 0xcd, 0xc8, 0xdb, 0x86, 0xe6,
- 0x74, 0x35, 0xe8, 0x9a, 0xa2, 0xd4, 0x94, 0xa5, 0x32, 0x35, 0x12, 0x53, 0x53, 0x90, 0xca, 0xf4,
- 0xfe, 0xb0, 0xc0, 0x9e, 0x3a, 0x3e, 0xb5, 0x1b, 0x1e, 0x98, 0xed, 0x95, 0x78, 0x80, 0xbe, 0x02,
- 0x67, 0x24, 0x99, 0xf0, 0xd3, 0x88, 0xc4, 0xcc, 0x3f, 0xd1, 0xa7, 0x58, 0xd2, 0x49, 0x74, 0x0a,
- 0x49, 0x7c, 0xa1, 0x70, 0xdc, 0x54, 0xcc, 0xae, 0x22, 0xea, 0x31, 0xfa, 0x0c, 0xca, 0xa7, 0x89,
- 0xd4, 0x99, 0x98, 0xae, 0xdb, 0xef, 0x13, 0x39, 0x55, 0x76, 0xa7, 0x89, 0x44, 0xf7, 0x61, 0x61,
- 0x72, 0xc2, 0x3c, 0x30, 0xc9, 0x82, 0x31, 0x74, 0x10, 0x78, 0xbf, 0x97, 0xa0, 0x39, 0x3d, 0x51,
- 0x6d, 0x28, 0xa5, 0x7c, 0x7c, 0x18, 0x29, 0xe5, 0xe8, 0x11, 0x34, 0x53, 0xc1, 0x13, 0xc1, 0xb3,
- 0x0b, 0x3f, 0x62, 0x67, 0x2c, 0x32, 0x07, 0x63, 0x8f, 0xd1, 0x43, 0x05, 0xa2, 0xa7, 0xf0, 0x51,
- 0x2a, 0x18, 0x1b, 0xa6, 0x5a, 0x77, 0x94, 0xa4, 0x64, 0xc0, 0x23, 0x9e, 0x5d, 0x98, 0x53, 0x5b,
- 0xbe, 0x74, 0xee, 0x4d, 0x7c, 0x4a, 0x83, 0x85, 0x49, 0x67, 0xa3, 0x28, 0x66, 0x62, 0x3c, 0x2f,
- 0x0f, 0x77, 0xe5, 0xd2, 0x7f, 0x5c, 0x74, 0xab, 0x40, 0x4f, 0x29, 0x1f, 0x9f, 0xf7, 0x29, 0xe5,
- 0xe8, 0x01, 0x94, 0xc3, 0x81, 0x30, 0x77, 0xd3, 0xb5, 0x0a, 0x56, 0x3e, 0x45, 0x51, 0x45, 0x5e,
- 0x9b, 0x41, 0x19, 0x0e, 0x84, 0xb7, 0x09, 0x15, 0x35, 0x40, 0x37, 0xa1, 0x3a, 0x10, 0xfe, 0x28,
- 0xd2, 0xa9, 0xa8, 0xe0, 0xca, 0x40, 0x1c, 0x45, 0x06, 0x0c, 0xf2, 0x14, 0x68, 0x70, 0x3f, 0xf2,
- 0x7e, 0x86, 0xe5, 0xff, 0xba, 0x69, 0xd0, 0x03, 0x58, 0xe4, 0xe9, 0xd9, 0xb6, 0x4f, 0x72, 0x8f,
- 0x91, 0xcd, 0x82, 0xc2, 0x0c, 0xd9, 0x50, 0x76, 0x26, 0x94, 0xd2, 0x84, 0xb2, 0x33, 0xa6, 0xdc,
- 0x07, 0x3d, 0xf4, 0x53, 0xc1, 0x4e, 0xf8, 0x5b, 0x93, 0x4d, 0x50, 0x50, 0x57, 0x23, 0x1e, 0x81,
- 0xfa, 0xb8, 0xe0, 0xd0, 0x43, 0xb0, 0x03, 0x16, 0x65, 0xc4, 0x97, 0x8c, 0x26, 0x71, 0x90, 0x7f,
- 0xb3, 0x8a, 0x17, 0x35, 0xd8, 0xcb, 0x31, 0xb4, 0x09, 0xcb, 0x01, 0xb9, 0x88, 0x78, 0xf8, 0x26,
- 0xf3, 0x25, 0xd1, 0xfd, 0x40, 0xd5, 0xa9, 0x39, 0x56, 0x34, 0xf6, 0xf5, 0xb4, 0x4b, 0x2d, 0xed,
- 0x11, 0xa8, 0xe6, 0xf2, 0xfb, 0x30, 0x5b, 0x42, 0x50, 0xd1, 0xa2, 0xcf, 0xf7, 0xa2, 0x6d, 0xef,
- 0xef, 0x12, 0xb8, 0x57, 0x5a, 0xa2, 0x4c, 0x93, 0x58, 0x32, 0xd5, 0x13, 0x8b, 0x0d, 0xc1, 0x7a,
- 0xe7, 0x86, 0x50, 0x7a, 0x8f, 0x86, 0xf0, 0x18, 0x96, 0x48, 0x1a, 0xfb, 0x82, 0xc9, 0x4c, 0x70,
- 0x7d, 0x57, 0x9b, 0xe8, 0x9a, 0x24, 0x55, 0xa1, 0x8c, 0xd1, 0x2b, 0x97, 0x6f, 0xe5, 0xca, 0xe5,
- 0xbb, 0x09, 0x0b, 0xd4, 0x4f, 0xc3, 0x73, 0x53, 0xd5, 0xd5, 0x19, 0x55, 0xdd, 0xa0, 0xdd, 0xf0,
- 0x3c, 0xcf, 0xe8, 0xf5, 0x6e, 0x30, 0xff, 0x7e, 0xdd, 0x60, 0x13, 0x1a, 0x61, 0x96, 0xfa, 0x4c,
- 0x88, 0x64, 0x2c, 0xec, 0xe2, 0x5d, 0xfc, 0x32, 0x4b, 0xdb, 0xca, 0x85, 0xeb, 0xa1, 0xb1, 0xbc,
- 0xbf, 0x2c, 0x58, 0xd9, 0x67, 0x11, 0xfb, 0x10, 0xaf, 0x8f, 0xbb, 0xd0, 0x30, 0xe1, 0x4f, 0xce,
- 0xb3, 0x9e, 0x03, 0x07, 0xc1, 0x87, 0xce, 0x95, 0x77, 0x08, 0xee, 0x95, 0xb8, 0x2f, 0x25, 0x32,
- 0x95, 0x06, 0xeb, 0x5d, 0xd2, 0xf0, 0x1c, 0x16, 0xda, 0xf4, 0x4d, 0x62, 0x36, 0xff, 0xbe, 0x3b,
- 0xf7, 0x9a, 0xb0, 0x98, 0x4f, 0xcf, 0x63, 0xf0, 0xb6, 0xa0, 0x3e, 0xfe, 0x88, 0xea, 0x33, 0x94,
- 0x8c, 0x24, 0x33, 0xd7, 0x68, 0x3e, 0xd0, 0xbd, 0x42, 0x86, 0x93, 0x5e, 0x21, 0xc3, 0x27, 0xdf,
- 0x40, 0xcd, 0x88, 0x17, 0x01, 0xcc, 0x1f, 0x75, 0x8e, 0x7a, 0xed, 0x7d, 0x67, 0x0e, 0xd5, 0xa1,
- 0x72, 0xd0, 0x3d, 0xde, 0x76, 0x2c, 0x63, 0xed, 0x38, 0x25, 0xe5, 0x57, 0xd8, 0xf1, 0x8e, 0x53,
- 0x46, 0x0d, 0xa8, 0x76, 0x92, 0xf8, 0xa0, 0xeb, 0x54, 0x9f, 0xfc, 0x6a, 0x41, 0xcd, 0xbc, 0x9f,
- 0xd0, 0x22, 0xd4, 0x71, 0xbb, 0xd7, 0xc6, 0xc7, 0x7a, 0x91, 0x06, 0x54, 0x8f, 0xfa, 0xb8, 0xd5,
- 0x71, 0x2c, 0x65, 0xbe, 0x6c, 0x2b, 0xb3, 0xa4, 0x16, 0xfc, 0xe1, 0xb0, 0xd5, 0x71, 0xca, 0xa8,
- 0x06, 0xe5, 0x97, 0xad, 0x8e, 0x53, 0x51, 0xd0, 0xb7, 0xbd, 0x6e, 0xcb, 0xa9, 0xaa, 0x6f, 0xb4,
- 0xf3, 0x39, 0xf3, 0x68, 0x01, 0x6a, 0xc7, 0x07, 0xb8, 0x7f, 0xd4, 0x3a, 0x74, 0x6a, 0xe8, 0x06,
- 0xd8, 0xb9, 0xc3, 0xef, 0xec, 0xfa, 0x07, 0xdf, 0xf5, 0x9d, 0xba, 0x5a, 0xf3, 0xb0, 0xdf, 0xf6,
- 0x5f, 0x39, 0x0d, 0x34, 0x0f, 0xa5, 0x0e, 0x76, 0xe0, 0xc9, 0x6f, 0x16, 0xdc, 0xb8, 0xf6, 0xfa,
- 0x41, 0x9f, 0x80, 0xd7, 0xea, 0x76, 0xd4, 0x4b, 0xf8, 0x8c, 0x07, 0x2c, 0xf0, 0xe5, 0x68, 0x20,
- 0xa9, 0xe0, 0xe6, 0xc6, 0x67, 0x82, 0x9f, 0x70, 0x16, 0x38, 0x73, 0xe8, 0x63, 0x58, 0x1d, 0x4a,
- 0x5f, 0x51, 0xa7, 0x18, 0x71, 0x92, 0x5d, 0xb2, 0x2c, 0xf4, 0x29, 0x3c, 0x32, 0x6f, 0xd7, 0xff,
- 0xa1, 0x96, 0xb6, 0x7e, 0x29, 0x41, 0xad, 0xf7, 0xac, 0xab, 0x5e, 0xe0, 0xe8, 0x35, 0xd8, 0x53,
- 0x97, 0x0b, 0x2a, 0x3e, 0x5d, 0x67, 0xbc, 0xc4, 0xef, 0x3c, 0x9c, 0xcd, 0x99, 0xe8, 0xce, 0x9b,
- 0x53, 0x6b, 0x4f, 0xa9, 0x72, 0x6a, 0xed, 0x19, 0x75, 0x36, 0xb5, 0xf6, 0x2c, 0x4d, 0x7b, 0x73,
- 0xe8, 0x39, 0xd4, 0x7b, 0x2c, 0x0e, 0x94, 0xd0, 0xd0, 0xad, 0xc2, 0x94, 0x82, 0x70, 0xef, 0xac,
- 0x5c, 0xc3, 0x8d, 0x22, 0xe7, 0x76, 0xef, 0xbe, 0xbe, 0xad, 0x7d, 0x1b, 0xea, 0x5f, 0x09, 0x8d,
- 0x92, 0x51, 0xb0, 0x11, 0x26, 0xe6, 0xef, 0xc9, 0x60, 0x5e, 0xff, 0x3e, 0xfd, 0x37, 0x00, 0x00,
- 0xff, 0xff, 0x6c, 0x25, 0x0b, 0xae, 0xb3, 0x0c, 0x00, 0x00,
+ // 1423 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0xdd, 0x6e, 0x1b, 0x37,
+ 0x16, 0xf6, 0xe8, 0xc7, 0x1a, 0x1d, 0x7b, 0xe4, 0x09, 0xe3, 0x8d, 0x27, 0x3f, 0x40, 0x9c, 0xc9,
+ 0x66, 0xe3, 0xcd, 0x62, 0x6d, 0xaf, 0x63, 0x18, 0xd9, 0x05, 0x82, 0xad, 0x6c, 0x2b, 0xa9, 0x01,
+ 0x47, 0x55, 0x28, 0xd9, 0x05, 0x72, 0x33, 0xa0, 0x38, 0xf4, 0x84, 0xe8, 0x68, 0x66, 0x4c, 0x8e,
+ 0xec, 0xb8, 0x40, 0x81, 0xde, 0x16, 0xe8, 0x4d, 0x1f, 0xa5, 0x37, 0x7d, 0x84, 0x3e, 0x4b, 0xef,
+ 0xfa, 0x0a, 0x05, 0x39, 0x94, 0x3c, 0xb2, 0x6b, 0x34, 0x01, 0x72, 0xa5, 0xc3, 0xef, 0x7c, 0xe4,
+ 0x1c, 0x1e, 0x7e, 0x87, 0x87, 0x82, 0xbb, 0x27, 0x2c, 0xda, 0xc8, 0x44, 0x9a, 0xa7, 0x72, 0x43,
+ 0xbe, 0x08, 0x32, 0x91, 0x7e, 0xb8, 0x58, 0xd7, 0x63, 0xd4, 0x1c, 0x91, 0x68, 0x44, 0xd6, 0x4f,
+ 0x58, 0xe4, 0xff, 0x5e, 0x87, 0x95, 0x3d, 0xc1, 0x48, 0xce, 0xfa, 0x4c, 0x4a, 0x9e, 0x26, 0x98,
+ 0x9d, 0x8e, 0x99, 0xcc, 0x7b, 0xd1, 0x39, 0xba, 0x07, 0x76, 0x16, 0x9d, 0xb7, 0xc3, 0x50, 0x48,
+ 0xcf, 0x5a, 0xb5, 0xd6, 0x9a, 0x78, 0x3a, 0x46, 0x08, 0x6a, 0x7c, 0x24, 0xb9, 0x57, 0xd1, 0xb8,
+ 0xb6, 0xd1, 0x1d, 0x98, 0x1f, 0x49, 0x2e, 0xc3, 0xc4, 0xab, 0x6a, 0xd4, 0x8c, 0x90, 0x0b, 0xd5,
+ 0x11, 0xe3, 0x5e, 0x4d, 0x83, 0xca, 0x44, 0xbb, 0xb0, 0x24, 0x99, 0x38, 0xe3, 0x49, 0x14, 0x24,
+ 0x2c, 0x3f, 0x4f, 0xc5, 0x37, 0x5e, 0x7d, 0xd5, 0x5a, 0x5b, 0xd8, 0xba, 0xbb, 0x3e, 0x0d, 0x6d,
+ 0xbd, 0x5f, 0x30, 0xba, 0x05, 0x01, 0xb7, 0xe4, 0xcc, 0x18, 0x6d, 0x43, 0x75, 0x1c, 0x73, 0x6f,
+ 0x5e, 0xcf, 0xf3, 0x4b, 0xf3, 0x8e, 0x24, 0x13, 0x87, 0x29, 0x25, 0x39, 0x4f, 0x93, 0x83, 0xe4,
+ 0x24, 0x15, 0x23, 0x6d, 0x62, 0x45, 0x47, 0xff, 0x06, 0x5b, 0x90, 0x3c, 0xc8, 0x2f, 0x32, 0xe6,
+ 0x35, 0x56, 0xad, 0xb5, 0xd6, 0x16, 0x2a, 0x4d, 0xc5, 0xed, 0xc1, 0xe0, 0x22, 0x63, 0xb8, 0x21,
+ 0x48, 0xae, 0x0c, 0x45, 0xcf, 0xc2, 0xa4, 0xa0, 0xdb, 0xd7, 0xe8, 0xbd, 0xfd, 0x6e, 0x41, 0xcf,
+ 0xc2, 0x44, 0xd3, 0xff, 0x03, 0xd5, 0x8c, 0x10, 0xaf, 0xa9, 0x63, 0x7a, 0x58, 0x66, 0x86, 0x89,
+ 0xca, 0x1b, 0x93, 0xb2, 0x1d, 0xc7, 0x26, 0x36, 0xac, 0xb8, 0x2a, 0x39, 0x24, 0x4b, 0x3c, 0x28,
+ 0x92, 0x43, 0xb2, 0x04, 0x3d, 0x86, 0x1a, 0x19, 0x0d, 0x85, 0xb7, 0xa0, 0x57, 0x59, 0x2a, 0xad,
+ 0xd2, 0x1e, 0x0d, 0x05, 0xd6, 0x4e, 0xb4, 0x07, 0x2d, 0xc9, 0x62, 0x46, 0xd5, 0x42, 0xc1, 0x28,
+ 0x0d, 0x99, 0xb7, 0xa8, 0xc3, 0x7b, 0x30, 0x93, 0x40, 0x43, 0x78, 0x93, 0x86, 0x4c, 0x07, 0xea,
+ 0xc8, 0x32, 0x84, 0xfe, 0x0f, 0xad, 0x21, 0x23, 0x82, 0x89, 0x80, 0xa6, 0x49, 0xce, 0x3e, 0xe4,
+ 0x9e, 0xa3, 0xbf, 0xe9, 0x95, 0x16, 0xd9, 0xd5, 0x84, 0xbd, 0xc2, 0x8f, 0x9d, 0x61, 0x79, 0x88,
+ 0x1e, 0x00, 0xd0, 0x80, 0x44, 0xe7, 0x41, 0xce, 0x78, 0xe8, 0xb5, 0x56, 0xad, 0x35, 0x07, 0xdb,
+ 0xb4, 0x1d, 0x9d, 0x0f, 0x18, 0x0f, 0xd1, 0x53, 0x58, 0xe2, 0x49, 0xc8, 0x8b, 0xdd, 0x06, 0x27,
+ 0x31, 0x89, 0xbc, 0xa5, 0x55, 0x6b, 0x6d, 0x11, 0xb7, 0x2e, 0xe1, 0x57, 0x31, 0x89, 0xd0, 0x7f,
+ 0xc1, 0xa3, 0xef, 0x89, 0x88, 0x94, 0x1e, 0x94, 0x41, 0x68, 0xce, 0x04, 0x97, 0x39, 0xa7, 0xd2,
+ 0x73, 0x75, 0x62, 0x56, 0x26, 0xfe, 0xbd, 0x59, 0x37, 0xda, 0x84, 0x66, 0xce, 0x47, 0x2c, 0xf8,
+ 0x36, 0x4d, 0x98, 0x77, 0x4b, 0x47, 0x7f, 0xbb, 0x14, 0xfd, 0x80, 0x8f, 0xd8, 0xbb, 0x34, 0x61,
+ 0xd8, 0xce, 0x8d, 0xe5, 0xff, 0x6c, 0xc1, 0xca, 0x0d, 0x12, 0x51, 0x87, 0x11, 0x13, 0xaa, 0xc5,
+ 0xee, 0x60, 0x65, 0xa2, 0x16, 0x54, 0x68, 0xa1, 0x72, 0x07, 0x57, 0x28, 0x57, 0x0c, 0x49, 0xa8,
+ 0x16, 0xb8, 0x83, 0x95, 0xa9, 0x10, 0x41, 0xa8, 0x56, 0xb7, 0x83, 0x95, 0xa9, 0x90, 0x9c, 0x50,
+ 0xad, 0x68, 0x07, 0x2b, 0x53, 0x21, 0x8c, 0x16, 0x5a, 0x75, 0xb0, 0x32, 0xd1, 0x32, 0xd4, 0xdf,
+ 0xb0, 0xee, 0x90, 0x6b, 0x11, 0x3a, 0xb8, 0x18, 0xa8, 0x0a, 0xea, 0x14, 0xb0, 0xad, 0x61, 0x33,
+ 0xf2, 0xb7, 0xa1, 0x35, 0x5b, 0x0d, 0xba, 0xa6, 0x28, 0x35, 0x65, 0xa9, 0x4c, 0x8d, 0x24, 0xd4,
+ 0x14, 0xa4, 0x32, 0xfd, 0x5f, 0x2d, 0x70, 0x66, 0x8e, 0x4f, 0xed, 0x86, 0x87, 0x66, 0x7b, 0x15,
+ 0x1e, 0xa2, 0xff, 0x81, 0x3b, 0x96, 0x4c, 0x04, 0x59, 0x4c, 0x12, 0x16, 0x9c, 0xe8, 0x53, 0xac,
+ 0xe8, 0x24, 0xba, 0xa5, 0x24, 0xbe, 0x52, 0x38, 0x6e, 0x29, 0x66, 0x4f, 0x11, 0xf5, 0x18, 0xdd,
+ 0x87, 0xe6, 0x19, 0x89, 0x79, 0x18, 0x9c, 0xa6, 0x52, 0xe7, 0xc3, 0xc6, 0xb6, 0x06, 0xde, 0xa6,
+ 0x12, 0xfd, 0x0b, 0xaa, 0x0a, 0xae, 0x5d, 0x2b, 0xea, 0xb7, 0xa9, 0x9c, 0xa9, 0xc9, 0xd3, 0x54,
+ 0xa2, 0x87, 0xb0, 0x30, 0x3d, 0x7e, 0x1e, 0x9a, 0xbc, 0xc1, 0x04, 0x3a, 0x08, 0xfd, 0x9f, 0x2a,
+ 0xd0, 0x9a, 0x9d, 0xa8, 0x76, 0x9b, 0x51, 0x3e, 0x39, 0xa9, 0x8c, 0x72, 0xf4, 0x04, 0x5a, 0x99,
+ 0xe0, 0xa9, 0xe0, 0xf9, 0x45, 0x10, 0xb3, 0x33, 0x16, 0x9b, 0x53, 0x73, 0x26, 0xe8, 0xa1, 0x02,
+ 0xd1, 0x73, 0xf8, 0x5b, 0x26, 0x18, 0x1b, 0x65, 0x5a, 0x94, 0x94, 0x64, 0x64, 0xc8, 0x63, 0x9e,
+ 0x5f, 0x98, 0x23, 0x5d, 0xbe, 0x74, 0xee, 0x4d, 0x7d, 0x4a, 0xa0, 0xa5, 0x49, 0x67, 0xe3, 0x38,
+ 0x61, 0x62, 0x32, 0xaf, 0x38, 0xf8, 0x95, 0x4b, 0xff, 0x71, 0xd9, 0xad, 0x02, 0x3d, 0xa5, 0x7c,
+ 0x22, 0x86, 0x53, 0xca, 0xd1, 0x23, 0xa8, 0x46, 0x43, 0x61, 0x2e, 0xae, 0x6b, 0xe5, 0xad, 0x7c,
+ 0x8a, 0xa2, 0x6e, 0x80, 0xc6, 0x0d, 0x94, 0xd1, 0x50, 0xf8, 0x9b, 0x50, 0x53, 0x03, 0x74, 0x1b,
+ 0xea, 0x43, 0x11, 0x8c, 0x63, 0x9d, 0x8a, 0x1a, 0xae, 0x0d, 0xc5, 0x51, 0x6c, 0xc0, 0xb0, 0x48,
+ 0x81, 0x06, 0xf7, 0x63, 0xff, 0x3b, 0x58, 0xfe, 0xb3, 0x6b, 0x08, 0x3d, 0x82, 0x45, 0x9e, 0x9d,
+ 0x6d, 0x07, 0xa4, 0xf0, 0x18, 0x4d, 0x2d, 0x28, 0xcc, 0x90, 0x0d, 0x65, 0x67, 0x4a, 0xa9, 0x4c,
+ 0x29, 0x3b, 0x13, 0xca, 0x43, 0xd0, 0xc3, 0x20, 0x13, 0xec, 0x84, 0x7f, 0x30, 0xd9, 0x04, 0x05,
+ 0xf5, 0x34, 0xe2, 0x13, 0xb0, 0x27, 0xd5, 0x88, 0x1e, 0x83, 0x13, 0xb2, 0x38, 0x27, 0x81, 0x64,
+ 0x34, 0x4d, 0xc2, 0xe2, 0x9b, 0x75, 0xbc, 0xa8, 0xc1, 0x7e, 0x81, 0xa1, 0x4d, 0x58, 0x0e, 0xc9,
+ 0x45, 0xcc, 0xa3, 0xf7, 0x79, 0x20, 0x89, 0x6e, 0x16, 0xaa, 0x88, 0xcd, 0xb1, 0xa2, 0x89, 0xaf,
+ 0xaf, 0x5d, 0x6a, 0x69, 0x9f, 0x40, 0xbd, 0xd0, 0xe6, 0xe7, 0xd9, 0x12, 0x82, 0x9a, 0xae, 0x88,
+ 0x62, 0x2f, 0xda, 0xf6, 0x7f, 0xab, 0x80, 0x77, 0xa5, 0x5f, 0xca, 0x2c, 0x4d, 0x24, 0x53, 0x0d,
+ 0xb3, 0xdc, 0x2d, 0xac, 0x8f, 0xee, 0x16, 0x95, 0x4f, 0xe8, 0x16, 0x4f, 0x61, 0x89, 0x64, 0x49,
+ 0x20, 0x98, 0xcc, 0x05, 0xd7, 0x17, 0xb9, 0x89, 0xae, 0x45, 0x32, 0x15, 0xca, 0x04, 0xbd, 0x72,
+ 0x33, 0xd7, 0xae, 0xdc, 0xcc, 0x9b, 0xb0, 0x40, 0x83, 0x2c, 0x3a, 0x37, 0x25, 0x5f, 0xbf, 0xa1,
+ 0xe4, 0x9b, 0xb4, 0x17, 0x9d, 0x17, 0x19, 0xbd, 0xde, 0x2a, 0xe6, 0x3f, 0xad, 0x55, 0x6c, 0x42,
+ 0x33, 0xca, 0xb3, 0x80, 0x09, 0x91, 0x4e, 0x84, 0x5d, 0xbe, 0xa8, 0x5f, 0xe7, 0x59, 0x47, 0xb9,
+ 0xb0, 0x1d, 0x19, 0xcb, 0xff, 0xc5, 0x82, 0x95, 0x7d, 0x16, 0xb3, 0xcf, 0xf1, 0x34, 0xb9, 0x0f,
+ 0x4d, 0x13, 0xfe, 0xf4, 0x3c, 0xed, 0x02, 0x38, 0x08, 0x3f, 0x77, 0xae, 0xfc, 0x43, 0xf0, 0xae,
+ 0xc4, 0x7d, 0x29, 0x91, 0x99, 0x34, 0x58, 0x1f, 0x93, 0x86, 0x97, 0xb0, 0xd0, 0xa1, 0xef, 0x53,
+ 0xb3, 0xf9, 0x4f, 0xdd, 0xb9, 0xdf, 0x82, 0xc5, 0x62, 0x7a, 0x11, 0x83, 0xbf, 0x05, 0xf6, 0xe4,
+ 0x23, 0xaa, 0x09, 0x51, 0x32, 0x96, 0xcc, 0x5c, 0xa3, 0xc5, 0x40, 0x37, 0x12, 0x19, 0x4d, 0x1b,
+ 0x89, 0x8c, 0x9e, 0x7d, 0x01, 0x0d, 0x23, 0x5e, 0x04, 0x30, 0x7f, 0xd4, 0x3d, 0xea, 0x77, 0xf6,
+ 0xdd, 0x39, 0x64, 0x43, 0xed, 0xa0, 0x77, 0xbc, 0xed, 0x5a, 0xc6, 0xda, 0x71, 0x2b, 0xca, 0xaf,
+ 0xb0, 0xe3, 0x1d, 0xb7, 0x8a, 0x9a, 0x50, 0xef, 0xa6, 0xc9, 0x41, 0xcf, 0xad, 0x3f, 0xfb, 0xc1,
+ 0x82, 0x86, 0x79, 0x5c, 0xa1, 0x45, 0xb0, 0x71, 0xa7, 0xdf, 0xc1, 0xc7, 0x7a, 0x91, 0x26, 0xd4,
+ 0x8f, 0x06, 0xb8, 0xdd, 0x75, 0x2d, 0x65, 0xbe, 0xee, 0x28, 0xb3, 0xa2, 0x16, 0xfc, 0xfa, 0xb0,
+ 0xdd, 0x75, 0xab, 0xa8, 0x01, 0xd5, 0xd7, 0xed, 0xae, 0x5b, 0x53, 0xd0, 0x97, 0xfd, 0x5e, 0xdb,
+ 0xad, 0xab, 0x6f, 0x74, 0x8a, 0x39, 0xf3, 0x68, 0x01, 0x1a, 0xc7, 0x07, 0x78, 0x70, 0xd4, 0x3e,
+ 0x74, 0x1b, 0xe8, 0x16, 0x38, 0x85, 0x23, 0xe8, 0xee, 0x06, 0x07, 0x5f, 0x0d, 0x5c, 0x5b, 0xad,
+ 0x79, 0x38, 0xe8, 0x04, 0x6f, 0xdc, 0x26, 0x9a, 0x87, 0x4a, 0x17, 0xbb, 0xf0, 0xec, 0x47, 0x0b,
+ 0x6e, 0x5d, 0x7b, 0x1a, 0xa1, 0x7f, 0x80, 0xdf, 0xee, 0x75, 0xd5, 0x33, 0xf9, 0x8c, 0x87, 0x2c,
+ 0x0c, 0xe4, 0x78, 0x28, 0xa9, 0xe0, 0xe6, 0xc6, 0x67, 0x82, 0x9f, 0x70, 0x16, 0xba, 0x73, 0xe8,
+ 0xef, 0xb0, 0x3a, 0x92, 0x81, 0xa2, 0xce, 0x30, 0x92, 0x34, 0xbf, 0x64, 0x59, 0xe8, 0x9f, 0xf0,
+ 0xc4, 0x3c, 0x6c, 0xff, 0x82, 0x5a, 0xd9, 0xfa, 0xbe, 0x02, 0x8d, 0xfe, 0x8b, 0x9e, 0x7a, 0x9e,
+ 0xa3, 0x77, 0xe0, 0xcc, 0x5c, 0x2e, 0xa8, 0xfc, 0xae, 0xbd, 0xe1, 0x99, 0x7e, 0xef, 0xf1, 0xcd,
+ 0x9c, 0xa9, 0xee, 0xfc, 0x39, 0xb5, 0xf6, 0x8c, 0x2a, 0x67, 0xd6, 0xbe, 0xa1, 0xce, 0x66, 0xd6,
+ 0xbe, 0x49, 0xd3, 0xfe, 0x1c, 0x7a, 0x09, 0x76, 0x9f, 0x25, 0xa1, 0x12, 0x1a, 0xba, 0x53, 0x9a,
+ 0x52, 0x12, 0xee, 0xbd, 0x95, 0x6b, 0xb8, 0x51, 0xe4, 0xdc, 0xee, 0xfd, 0x77, 0x77, 0xb5, 0x6f,
+ 0x43, 0xfd, 0x65, 0xa1, 0x71, 0x3a, 0x0e, 0x37, 0xa2, 0xd4, 0xfc, 0x77, 0x19, 0xce, 0xeb, 0xdf,
+ 0xe7, 0x7f, 0x04, 0x00, 0x00, 0xff, 0xff, 0xee, 0xb9, 0x0b, 0x7d, 0xd0, 0x0c, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
diff --git a/feg/gateway/docker/README.md b/feg/gateway/docker/README.md
index a3ba02fdbcd4..14d1681bfcab 120000
--- a/feg/gateway/docker/README.md
+++ b/feg/gateway/docker/README.md
@@ -1 +1 @@
-../../../docs/readmes/feg/legacy/docker_setup.md
\ No newline at end of file
+../../../docs/readmes/feg/docker.md
\ No newline at end of file
diff --git a/feg/gateway/go.mod b/feg/gateway/go.mod
index cc932fcd75df..390776a9b222 100644
--- a/feg/gateway/go.mod
+++ b/feg/gateway/go.mod
@@ -29,7 +29,7 @@ require (
github.com/go-openapi/swag v0.19.5
github.com/go-redis/redis v6.14.1+incompatible
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
- github.com/golang/protobuf v1.4.3
+ github.com/golang/protobuf v1.5.2
github.com/ishidawataru/sctp v0.0.0-20191218070446-00ab2ac2db07
github.com/mitchellh/mapstructure v1.3.3 // indirect
github.com/pkg/errors v0.9.1
@@ -40,13 +40,13 @@ require (
github.com/stretchr/objx v0.3.0 // indirect
github.com/stretchr/testify v1.6.1
github.com/thoas/go-funk v0.7.0
- github.com/wmnsk/go-gtp v0.7.17
+ github.com/wmnsk/go-gtp v0.7.20
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 // indirect
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b
golang.org/x/sys v0.0.0-20201018230417-eeed37f84f13 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
google.golang.org/grpc v1.33.2
- google.golang.org/protobuf v1.25.0
+ google.golang.org/protobuf v1.26.0
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 // indirect
layeh.com/radius v0.0.0-20200615152116-663b41c3bf86
magma/feg/cloud/go v0.0.0
diff --git a/feg/gateway/go.sum b/feg/gateway/go.sum
index 06c6aa78a965..e96a6a7dca01 100644
--- a/feg/gateway/go.sum
+++ b/feg/gateway/go.sum
@@ -76,12 +76,10 @@ github.com/corbym/gocrest v1.0.3/go.mod h1:maVFL5lbdS2PgfOQgGRWDYTeunSWQeiEgoNdT
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/etcd v3.3.12+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
-github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
-github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -260,8 +258,9 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
-github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
-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.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
+github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
@@ -273,8 +272,7 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
github.com/google/go-cmp v0.4.0/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.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M=
-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/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
@@ -539,7 +537,6 @@ github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzG
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
github.com/rubyist/circuitbreaker v2.2.1+incompatible/go.mod h1:Ycs3JgJADPuzJDwffe12k6BZT8hxVi6lFK+gWYJLN4A=
-github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
@@ -573,7 +570,6 @@ github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkU
github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
-github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8=
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
@@ -583,7 +579,6 @@ github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzu
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.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@@ -611,7 +606,6 @@ github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhV
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/toqueteos/webbrowser v1.2.0/go.mod h1:XWoZq4cyp9WeUeak7w7LXRUQf1F1ATJMir8RTqb4ayM=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
-github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v0.0.0-20170224212429-dcecefd839c4 h1:gKMu1Bf6QINDnvyZuTaACm9ofY+PRh+5vFz4oxBZeF8=
@@ -627,10 +621,8 @@ github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17
github.com/wadey/gocovmerge v0.0.0-20160331181800-b5bfa59ec0ad h1:W0LEBv82YCGEtcmPA3uNZBI33/qF//HAAs3MawDjRa0=
github.com/wadey/gocovmerge v0.0.0-20160331181800-b5bfa59ec0ad/go.mod h1:Hy8o65+MXnS6EwGElrSRjUzQDLXreJlzYLlWiHtt8hM=
github.com/warthog618/sms v0.3.0/go.mod h1:+bYZGeBxu003sxD5xhzsrIPBAjPBzTABsRTwSpd7ld4=
-github.com/wmnsk/go-gtp v0.7.15 h1:D0L2ISdfsVwzHvN/l7uyTvdqewUl+p0BDFElN0p7Uy0=
-github.com/wmnsk/go-gtp v0.7.15/go.mod h1:v1psjZ7skpPSDegH23Amg9rNufs0BoXNM+GBtW5t58I=
-github.com/wmnsk/go-gtp v0.7.17 h1:Q/zZopp/6mJPgqz5kb/yseOYTQ7v/E4Hp99Y4DzwnyY=
-github.com/wmnsk/go-gtp v0.7.17/go.mod h1:IQ5tTgk1EDaKLLAum2vzYheKX9JeRngM1fm9ohdXAac=
+github.com/wmnsk/go-gtp v0.7.20 h1:N8aobzvxWz5l/lC1qPewuPyN6jL7O2Sdoe92JiGn/MM=
+github.com/wmnsk/go-gtp v0.7.20/go.mod h1:qdjTIBWIWjsNJdGs1EpmbcLjakUDPP7nRcEfKr2g1GQ=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
@@ -649,7 +641,6 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
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-20181106171534-e4dc69e5b2fd/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
-golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
@@ -661,8 +652,6 @@ golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190907121410-71b5226ff739 h1:Gc7JIyxvWgD6m+QmVryY0MstDORNYididDGxgZ6Tnpk=
golang.org/x/crypto v0.0.0-20190907121410-71b5226ff739/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
-golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 h1:pLI5jrR7OSLijeIDcmRxNmw2api+jEfxLoykJVice/E=
@@ -702,8 +691,6 @@ golang.org/x/net v0.0.0-20200202094626-16171245cfb2 h1:CCH4IOTTfewWjGOlSp+zGcjut
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA=
-golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b h1:uwuIcX0g4Yl1NC5XAz37xsr2lTtcqevgzYNVt49waME=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -725,7 +712,6 @@ golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -800,8 +786,6 @@ google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRn
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
-google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a h1:Ob5/580gVHBJZgXnff1cZDbG+xLtMVE5mDRTe+nIsX4=
-google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
@@ -817,7 +801,6 @@ google.golang.org/grpc v1.27.1 h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk=
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.31.0 h1:T7P4R73V3SSDPhH7WW7ATbfViLtmamH0DKrP3f9AuDI=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
-google.golang.org/grpc v1.33.0/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
google.golang.org/grpc v1.33.2 h1:EQyQC3sa8M+p6Ulc8yy9SWSS2GVwyRc83gAbG8lrl4o=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
@@ -826,10 +809,12 @@ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQ
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
-google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
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=
gopkg.in/DATA-DOG/go-sqlmock.v1 v1.3.0 h1:FVCohIoYO7IJoDDVpV2pdq7SgrMH6wHnuTyrdrxJNoY=
gopkg.in/DATA-DOG/go-sqlmock.v1 v1.3.0/go.mod h1:OdE7CF6DbADk7lN8LIKRzRJTTZXIjtWgA5THM5lhBAw=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
diff --git a/feg/gateway/services/aaa/test/pipelined/main.go b/feg/gateway/services/aaa/test/pipelined/main.go
index 7d0f7437cae8..56d23162b7ef 100644
--- a/feg/gateway/services/aaa/test/pipelined/main.go
+++ b/feg/gateway/services/aaa/test/pipelined/main.go
@@ -60,11 +60,11 @@ func (c *DummyPipelined) ActivateFlows(
ctx context.Context, req *protos.ActivateFlowsRequest) (res *protos.ActivateFlowsResult, err error) {
res = &protos.ActivateFlowsResult{
- DynamicRuleResults: []*protos.RuleModResult{},
+ PolicyResults: []*protos.RuleModResult{},
}
- for _, dynRule := range req.GetDynamicRules() {
- res.DynamicRuleResults = append(res.DynamicRuleResults, &protos.RuleModResult{
- RuleId: dynRule.GetId(),
+ for _, policyRule := range req.GetPolicies() {
+ res.PolicyResults = append(res.PolicyResults, &protos.RuleModResult{
+ RuleId: policyRule.GetRule().GetId(),
Result: protos.RuleModResult_SUCCESS,
})
}
diff --git a/feg/gateway/services/s8_proxy/client_api.go b/feg/gateway/services/s8_proxy/client_api.go
index 428eb5783a68..fde77898f2b1 100644
--- a/feg/gateway/services/s8_proxy/client_api.go
+++ b/feg/gateway/services/s8_proxy/client_api.go
@@ -17,11 +17,14 @@ import (
"context"
"errors"
"fmt"
+ "strings"
"magma/feg/cloud/go/protos"
"magma/feg/gateway/registry"
+ "magma/orc8r/lib/go/util"
"github.com/golang/glog"
+ "google.golang.org/grpc"
)
type s8ProxyClient struct {
@@ -62,7 +65,15 @@ func SendEcho(req *protos.EchoRequest) (*protos.EchoResponse, error) {
}
func getS8ProxyClient() (*s8ProxyClient, error) {
- conn, err := registry.GetConnection(registry.S8_PROXY)
+ var (
+ conn *grpc.ClientConn
+ err error
+ )
+ if util.GetEnvBool("USE_REMOTE_S8_PROXY") {
+ conn, err = registry.Get().GetSharedCloudConnection(strings.ToLower(registry.S8_PROXY))
+ } else {
+ conn, err = registry.GetConnection(registry.S8_PROXY)
+ }
if err != nil {
errMsg := fmt.Sprintf("S8 Proxy client initialization error: %s", err)
glog.Error(errMsg)
diff --git a/feg/gateway/services/s8_proxy/servicers/mock_pgw/cs.go b/feg/gateway/services/s8_proxy/servicers/mock_pgw/cs.go
index 985a9cc7d45f..219c8791aa14 100644
--- a/feg/gateway/services/s8_proxy/servicers/mock_pgw/cs.go
+++ b/feg/gateway/services/s8_proxy/servicers/mock_pgw/cs.go
@@ -186,6 +186,15 @@ func (mPgw *MockPgw) getHandleCreateSessionRequest() gtpv2.HandlerFunc {
}
}
+ qosPCI := uint8(0)
+ if bearer.QoSProfile.PCI {
+ qosPCI = 1
+ }
+ qosPVI := uint8(0)
+ if bearer.QoSProfile.PVI {
+ qosPVI = 1
+ }
+
// send
csRspFromPGW := message.NewCreateSessionResponse(
sgwTEIDc, msg.Sequence(),
@@ -198,6 +207,9 @@ func (mPgw *MockPgw) getHandleCreateSessionRequest() gtpv2.HandlerFunc {
ie.NewEPSBearerID(bearer.EBI),
pgwFTEIDu,
ie.NewChargingID(bearer.ChargingID),
+ ie.NewBearerQoS(qosPCI, bearer.QoSProfile.PL, qosPVI,
+ bearer.QoSProfile.QCI, bearer.QoSProfile.MBRUL, bearer.QoSProfile.MBRDL,
+ bearer.QoSProfile.GBRUL, bearer.QoSProfile.GBRDL),
))
session.AddTEID(gtpv2.IFTypeS5S8PGWGTPC, pgwFTEIDc.MustTEID())
@@ -333,7 +345,8 @@ func createQosIE(qp *gtpv2.QoSProfile) *ie.IE {
}
-func (mPgw *MockPgw) getHandleCreateSessionRequestWithDeniedService(errorCause uint8) gtpv2.HandlerFunc {
+// getHandleCreateSessionRequestWithErrorCause Responds with an arbitrary error cause
+func (mPgw *MockPgw) getHandleCreateSessionRequestWithErrorCause(errorCause uint8) gtpv2.HandlerFunc {
return func(c *gtpv2.Conn, sgwAddr net.Addr, msg message.Message) error {
fmt.Println("mock PGW received a CreateSessionRequest, but returning ERROR")
csReqFromSGW := msg.(*message.CreateSessionRequest)
@@ -361,7 +374,8 @@ func (mPgw *MockPgw) getHandleCreateSessionRequestWithDeniedService(errorCause u
}
}
-func (mPgw *MockPgw) getHandleCreateSessionRequestWithMissingIE() gtpv2.HandlerFunc {
+// getHandleCreateSessionResponseWithMissingIE responds with a CreateSessionResponse that has a missing field
+func (mPgw *MockPgw) getHandleCreateSessionResponseWithMissingIE() gtpv2.HandlerFunc {
return func(c *gtpv2.Conn, sgwAddr net.Addr, msg message.Message) error {
fmt.Println("mock PGW received a CreateSessionRequest, but returning ERROR")
csReqFromSGW := msg.(*message.CreateSessionRequest)
@@ -393,3 +407,31 @@ func (mPgw *MockPgw) getHandleCreateSessionRequestWithMissingIE() gtpv2.HandlerF
return nil
}
}
+
+// getHandleCreateSessionRequestWithMissingIE responds with a CauseMandatoryIEMissing
+func (mPgw *MockPgw) getHandleCreateSessionRequestWithMissingIE(missingIE *ie.IE) gtpv2.HandlerFunc {
+ return func(c *gtpv2.Conn, sgwAddr net.Addr, msg message.Message) error {
+ fmt.Println("mock PGW received a CreateSessionRequest, but returning ERROR")
+ csReqFromSGW := msg.(*message.CreateSessionRequest)
+ sgwTEID := csReqFromSGW.SenderFTEIDC
+ if sgwTEID != nil {
+ _, err := sgwTEID.TEID()
+ if err != nil {
+ return err
+ }
+ } else {
+ return >pv2.RequiredIEMissingError{Type: ie.FullyQualifiedTEID}
+ }
+
+ // Mising pgwFTEID and bearer pgwFTEIDu
+ csRspFromPGW := message.NewCreateSessionResponse(
+ sgwTEID.MustTEID(), msg.Sequence(),
+ ie.NewCause(gtpv2.CauseMandatoryIEMissing, 0, 0, 0, missingIE),
+ )
+
+ if err := c.RespondTo(sgwAddr, csReqFromSGW, csRspFromPGW); err != nil {
+ return err
+ }
+ return nil
+ }
+}
diff --git a/feg/gateway/services/s8_proxy/servicers/mock_pgw/mock_pgw.go b/feg/gateway/services/s8_proxy/servicers/mock_pgw/mock_pgw.go
index 62f34a6e3f15..e3009d040501 100644
--- a/feg/gateway/services/s8_proxy/servicers/mock_pgw/mock_pgw.go
+++ b/feg/gateway/services/s8_proxy/servicers/mock_pgw/mock_pgw.go
@@ -89,13 +89,19 @@ func (mPgw *MockPgw) Start(ctx context.Context, pgwAddrsStr string) error {
func (mPgw *MockPgw) SetCreateSessionWithErrorCause(errorCause uint8) {
mPgw.AddHandler(
message.MsgTypeCreateSessionRequest,
- mPgw.getHandleCreateSessionRequestWithDeniedService(errorCause))
+ mPgw.getHandleCreateSessionRequestWithErrorCause(errorCause))
}
-func (mPgw *MockPgw) SetCreateSessionWithMissingIE() {
+func (mPgw *MockPgw) SetCreateSessionResponseWithMissingIE() {
mPgw.AddHandler(
message.MsgTypeCreateSessionRequest,
- mPgw.getHandleCreateSessionRequestWithMissingIE())
+ mPgw.getHandleCreateSessionResponseWithMissingIE())
+}
+
+func (mPgw *MockPgw) SetCreateSessionRequestWithMissingIE(missingIE *ie.IE) {
+ mPgw.AddHandler(
+ message.MsgTypeCreateSessionRequest,
+ mPgw.getHandleCreateSessionRequestWithMissingIE(missingIE))
}
// ONLY FOR DEBUGGING PURPOSES
diff --git a/feg/gateway/services/s8_proxy/servicers/proto_conversions.go b/feg/gateway/services/s8_proxy/servicers/proto_conversions.go
index e1ca481a7d72..7783889f3437 100644
--- a/feg/gateway/services/s8_proxy/servicers/proto_conversions.go
+++ b/feg/gateway/services/s8_proxy/servicers/proto_conversions.go
@@ -26,22 +26,14 @@ import (
// the message is proper it also returns the session. In case it there is an error it returns
// the cause of error
func parseCreateSessionResponse(msg message.Message) (csRes *protos.CreateSessionResponsePgw, err error) {
+ //glog.V(4).Infof("Received Create Session Response (gtp):\n%s", message.Prettify(msg))
csResGtp := msg.(*message.CreateSessionResponse)
glog.V(2).Infof("Received Create Session Response (gtp):\n%s", csResGtp.String())
-
csRes = &protos.CreateSessionResponsePgw{}
// check Cause value first.
if causeIE := csResGtp.Cause; causeIE != nil {
- cause, err2 := causeIE.Cause()
- if err2 != nil {
- err = fmt.Errorf("Couldn't check cause of csRes: %s", err2)
- return
- }
- if cause != gtpv2.CauseRequestAccepted {
- csRes.GtpError = &protos.GtpError{
- Cause: uint32(cause),
- Msg: fmt.Sprintf("Message with sequence # %d not accepted", msg.Sequence()),
- }
+ csRes.GtpError, err = handleCause(causeIE, msg)
+ if err != nil || csRes.GtpError != nil {
return
}
// If we get here, the message will be processed
@@ -117,6 +109,14 @@ func parseCreateSessionResponse(msg message.Message) (csRes *protos.CreateSessio
if err != nil {
return
}
+
+ case ie.BearerQoS:
+ // save for testing purposes
+ bearerCtx.Qos, err = handleQOStoProto(childIE)
+ if err != nil {
+ return
+ }
+ bearerCtx.ValidQos = true
}
}
csRes.BearerContext = bearerCtx
@@ -132,24 +132,19 @@ func parseCreateSessionResponse(msg message.Message) (csRes *protos.CreateSessio
// the cause of error
func parseDelteSessionResponse(msg message.Message) (
dsRes *protos.DeleteSessionResponsePgw, err error) {
+ //glog.V(4).Infof("Received Delete Session Response (gtp):\n%s", (msg))
cdResGtp := msg.(*message.DeleteSessionResponse)
glog.V(2).Infof("Received Delete Session Response (gtp):\n%s", cdResGtp.String())
dsRes = &protos.DeleteSessionResponsePgw{}
// check Cause value first.
if causeIE := cdResGtp.Cause; causeIE != nil {
- cause, err2 := causeIE.Cause()
- if err2 != nil {
- err = fmt.Errorf("Couldn't check cause of delete session response: %s", err2)
- return
- }
- if cause != gtpv2.CauseRequestAccepted {
- dsRes.GtpError = &protos.GtpError{
- Cause: uint32(cause),
- Msg: fmt.Sprintf("DeleteSessionRequest with sequence # %d not accepted", msg.Sequence()),
- }
+
+ dsRes.GtpError, err = handleCause(causeIE, msg)
+ if err != nil || dsRes.GtpError != nil {
return
}
+ // If we get here, the message will be processed
} else {
dsRes.GtpError = errorIeMissing(ie.Cause)
return
@@ -165,6 +160,29 @@ func errorIeMissing(missingIE uint8) *protos.GtpError {
}
}
+func handleCause(causeIE *ie.IE, msg message.Message) (*protos.GtpError, error) {
+ cause, err := causeIE.Cause()
+ if err != nil {
+ return nil, fmt.Errorf("Couldn't check cause of %s: %s", msg.MessageTypeName(), err)
+ }
+
+ switch cause {
+ case gtpv2.CauseRequestAccepted:
+ return nil, nil
+ default:
+ gtpErrorString := fmt.Sprintf("%s with sequence # %d not accepted. Cause: %d", msg.MessageTypeName(), msg.Sequence(), cause)
+ offendingIE, _ := causeIE.OffendingIE()
+ if offendingIE != nil {
+ gtpErrorString = fmt.Sprintf("%s %s: %d %s", gtpErrorString, " With Offending IE", offendingIE.Type, offendingIE)
+ }
+ glog.Warning(gtpErrorString)
+ return &protos.GtpError{
+ Cause: uint32(cause),
+ Msg: gtpErrorString,
+ }, nil
+ }
+}
+
// handleFTEID converts FTEID IE format into Proto format returning also the type of interface
func handleFTEID(fteidIE *ie.IE) (*protos.Fteid, uint8, error) {
interfaceType, err := fteidIE.InterfaceType()
@@ -221,3 +239,57 @@ func handlePDNAddressAllocation(paaIE *ie.IE) (*protos.PdnAddressAllocation, pro
}
return &paa, pdnType, nil
}
+
+func handleQOStoProto(qosIE *ie.IE) (*protos.QosInformation, error) {
+ qos := &protos.QosInformation{}
+
+ // priority level
+ pl, err := qosIE.PriorityLevel()
+ if err != nil {
+ return nil, err
+ }
+ qos.PriorityLevel = uint32(pl)
+
+ // qci label
+ qci, err := qosIE.QCILabel()
+ if err != nil {
+ return nil, err
+ }
+ qos.Qci = uint32(qci)
+
+ // Preemption Capability
+ if qosIE.PreemptionCapability() {
+ qos.PreemptionCapability = 1
+ }
+
+ // Preemption Vulnerability
+ if qosIE.PreemptionVulnerability() {
+ qos.PreemptionVulnerability = 1
+ }
+
+ // maximum bitrate
+ mAmbr := &protos.Ambr{}
+ mAmbr.BrUl, err = qosIE.MBRForUplink()
+ if err != nil {
+ return nil, err
+ }
+ mAmbr.BrDl, err = qosIE.MBRForDownlink()
+ if err != nil {
+ return nil, err
+ }
+ qos.Mbr = mAmbr
+
+ // granted bitrate
+ gAmbr := &protos.Ambr{}
+ gAmbr.BrUl, err = qosIE.GBRForUplink()
+ if err != nil {
+ return nil, err
+ }
+ gAmbr.BrDl, err = qosIE.GBRForDownlink()
+ if err != nil {
+ return nil, err
+ }
+ qos.Gbr = gAmbr
+
+ return qos, nil
+}
diff --git a/feg/gateway/services/s8_proxy/servicers/s8_proxy.go b/feg/gateway/services/s8_proxy/servicers/s8_proxy.go
index 441d09c0b896..f1d705119d66 100644
--- a/feg/gateway/services/s8_proxy/servicers/s8_proxy.go
+++ b/feg/gateway/services/s8_proxy/servicers/s8_proxy.go
@@ -108,6 +108,12 @@ func (s *S8Proxy) CreateSession(ctx context.Context, req *protos.CreateSessionRe
}
func (s *S8Proxy) DeleteSession(ctx context.Context, req *protos.DeleteSessionRequestPgw) (*protos.DeleteSessionResponsePgw, error) {
+ err := validateDeleteSessionRequest(req)
+ if err != nil {
+ err = fmt.Errorf("Delete Session failed for IMSI %s:, couldn't validate request: %s", req.Imsi, err)
+ glog.Error(err)
+ return nil, err
+ }
cPgwUDPAddr, err := s.configOrRequestedPgwAddress(req.PgwAddrs)
if err != nil {
err = fmt.Errorf("Delete Session failed for IMSI %s: %s", req.Imsi, err)
@@ -153,8 +159,16 @@ func (s *S8Proxy) configOrRequestedPgwAddress(pgwAddrsFromRequest string) (*net.
}
func validateCreateSessionRequest(csr *protos.CreateSessionRequestPgw) error {
- if csr.BearerContext == nil || csr.BearerContext.UserPlaneFteid == nil || csr.BearerContext.Id == 0 {
+ if csr.BearerContext == nil || csr.BearerContext.UserPlaneFteid == nil || csr.BearerContext.Id == 0 ||
+ csr.BearerContext.Qos == nil {
return fmt.Errorf("CreateSessionRequest missing fields %+v", csr)
}
return nil
}
+
+func validateDeleteSessionRequest(dsr *protos.DeleteSessionRequestPgw) error {
+ if dsr.CPgwFteid == nil || dsr.Imsi == "" {
+ return fmt.Errorf("DeleteSessionRequest missing fields %+v", dsr)
+ }
+ return nil
+}
diff --git a/feg/gateway/services/s8_proxy/servicers/s8_proxy_test.go b/feg/gateway/services/s8_proxy/servicers/s8_proxy_test.go
index f5eb19b700af..1d03072d59ef 100644
--- a/feg/gateway/services/s8_proxy/servicers/s8_proxy_test.go
+++ b/feg/gateway/services/s8_proxy/servicers/s8_proxy_test.go
@@ -14,7 +14,6 @@ package servicers
import (
"context"
"fmt"
- "regexp"
"strconv"
"strings"
"sync"
@@ -80,14 +79,26 @@ func TestS8proxyCreateAndDeleteSession(t *testing.T) {
assert.Equal(t, PAA, csRes.Paa.Ipv4Address)
assert.Equal(t, "", csRes.Paa.Ipv6Address)
- // check received QOS
+ // check QOS received at PGW
sentQos := csReq.BearerContext.Qos
- receivedQos := mockPgw.LastQos
- assert.Equal(t, sentQos.Gbr.BrDl, receivedQos.Gbr.BrDl)
- assert.Equal(t, sentQos.Gbr.BrUl, receivedQos.Gbr.BrUl)
- assert.Equal(t, sentQos.Mbr.BrDl, receivedQos.Mbr.BrDl)
- assert.Equal(t, sentQos.Mbr.BrUl, receivedQos.Mbr.BrUl)
- assert.Equal(t, sentQos.Qci, receivedQos.Qci)
+ receivedAtPGWQos := mockPgw.LastQos
+ assert.Equal(t, sentQos.Gbr.BrDl, receivedAtPGWQos.Gbr.BrDl)
+ assert.Equal(t, sentQos.Gbr.BrUl, receivedAtPGWQos.Gbr.BrUl)
+ assert.Equal(t, sentQos.Mbr.BrDl, receivedAtPGWQos.Mbr.BrDl)
+ assert.Equal(t, sentQos.Mbr.BrUl, receivedAtPGWQos.Mbr.BrUl)
+ assert.Equal(t, sentQos.Qci, receivedAtPGWQos.Qci)
+
+ // check QOS received at Response (should be the same as the sent)
+
+ assert.NotEmpty(t, csRes.BearerContext.Qos)
+ receivedQOS := csRes.BearerContext.Qos
+
+ assert.True(t, csRes.BearerContext.ValidQos)
+ assert.Equal(t, sentQos.Gbr.BrDl, receivedQOS.Gbr.BrDl)
+ assert.Equal(t, sentQos.Gbr.BrUl, receivedQOS.Gbr.BrUl)
+ assert.Equal(t, sentQos.Mbr.BrDl, receivedQOS.Mbr.BrDl)
+ assert.Equal(t, sentQos.Mbr.BrUl, receivedQOS.Mbr.BrUl)
+ assert.Equal(t, sentQos.Qci, receivedQOS.Qci)
// ------------------------
// ---- Delete Session ----
@@ -154,6 +165,23 @@ func TestS8proxyRepeatedCreateSession(t *testing.T) {
assert.Equal(t, PgwTEIDc, csRes.CPgwFteid.Teid)
}
+func TestS8proxyCreateWithMissingParam(t *testing.T) {
+ // set up client ans server
+ s8p, mockPgw := startSgwAndPgw(t, GtpTimeoutForTest)
+ defer mockPgw.Close()
+
+ // ------------------------
+ // ---- Create Session ----
+ csReq := getDefaultCreateSessionRequest(mockPgw.LocalAddr().String())
+ csReq.BearerContext = nil
+
+ // Send and receive Create Session Request
+ _, err := s8p.CreateSession(context.Background(), csReq)
+ assert.Error(t, err)
+}
+
+// TestS8ProxyDeleteSessionAfterClientRestars test if s8_proxy is able to handle an already
+// created session after s8 has been restarted.
func TestS8ProxyDeleteSessionAfterClientRestars(t *testing.T) {
// set up client ans server
s8p, mockPgw := startSgwAndPgw(t, time.Second*600)
@@ -203,8 +231,8 @@ func TestS8ProxyDeleteInexistentSession(t *testing.T) {
// ------------------------
// ---- Delete Session inexistent session ----
- cdReq := &protos.DeleteSessionRequestPgw{Imsi: "000000000000015"}
- cdReq = &protos.DeleteSessionRequestPgw{
+ dsReq := &protos.DeleteSessionRequestPgw{Imsi: "000000000000015"}
+ dsReq = &protos.DeleteSessionRequestPgw{
PgwAddrs: mockPgw.LocalAddr().String(),
Imsi: "000000000000015",
BearerId: 4,
@@ -214,12 +242,24 @@ func TestS8ProxyDeleteInexistentSession(t *testing.T) {
Teid: 87,
},
}
- _, err := s8p.DeleteSession(context.Background(), cdReq)
+ _, err := s8p.DeleteSession(context.Background(), dsReq)
assert.Error(t, err)
assert.Equal(t, mockPgw.LastTEIDc, uint32(87))
}
-func TestS8proxyCreateSessionWithErrors(t *testing.T) {
+func TestS8ProxyDeleteWithMissingParamaters(t *testing.T) {
+ s8p, mockPgw := startSgwAndPgw(t, 200*time.Millisecond)
+ defer mockPgw.Close()
+
+ // ------------------------
+ // ---- Delete Session inexistent session ----
+ // create a bad create session request
+ dsReq := getDeleteSessionRequest(mockPgw.LocalAddr().String(), nil)
+ _, err := s8p.DeleteSession(context.Background(), dsReq)
+ assert.Error(t, err)
+}
+
+func TestS8proxyCreateSessionWithServiceDenial(t *testing.T) {
// set up client ans server
s8p, mockPgw := startSgwAndPgw(t, GtpTimeoutForTest)
defer mockPgw.Close()
@@ -228,10 +268,6 @@ func TestS8proxyCreateSessionWithErrors(t *testing.T) {
// ---- Create Session ----
csReq := getDefaultCreateSessionRequest(mockPgw.LocalAddr().String())
- // ------------------------
- // ---- Create Session ----
- csReq = getDefaultCreateSessionRequest(mockPgw.LocalAddr().String())
-
// PGW denies service
mockPgw.SetCreateSessionWithErrorCause(gtpv2.CauseServiceDenied)
csRes, err := s8p.CreateSession(context.Background(), csReq)
@@ -239,18 +275,49 @@ func TestS8proxyCreateSessionWithErrors(t *testing.T) {
assert.NotEmpty(t, csRes)
assert.NotEmpty(t, csRes.GtpError)
assert.Equal(t, gtpv2.CauseServiceDenied, uint8(csRes.GtpError.Cause))
+}
+
+func TestS8proxyCreateSessionWithMissingIEonResponse(t *testing.T) {
+ // set up client ans server
+ s8p, mockPgw := startSgwAndPgw(t, GtpTimeoutForTest)
+ defer mockPgw.Close()
+
+ // ------------------------
+ // ---- Create Session ----
+ csReq := getDefaultCreateSessionRequest(mockPgw.LocalAddr().String())
// s8_proxy forces a missing IE
- mockPgw.SetCreateSessionWithMissingIE()
- csRes, err = s8p.CreateSession(context.Background(), csReq)
+ mockPgw.SetCreateSessionResponseWithMissingIE()
+ csRes, err := s8p.CreateSession(context.Background(), csReq)
assert.NoError(t, err)
assert.NotEmpty(t, csRes)
assert.NotEmpty(t, csRes.GtpError)
assert.Equal(t, gtpv2.CauseMandatoryIEMissing, uint8(csRes.GtpError.Cause))
// check the error code is FullyQualifiedTEID
- re := regexp.MustCompile("[0-9]+")
- msg := re.FindString(csRes.GtpError.Msg)
- assert.Equal(t, strconv.FormatUint(uint64(ie.FullyQualifiedTEID), 10), msg)
+
+ assert.Contains(t, csRes.GtpError.Msg, strconv.FormatUint(uint64(ie.FullyQualifiedTEID), 10))
+}
+
+func TestS8proxyCreateSessionWithMissingIEMessage(t *testing.T) {
+ // set up client ans server
+ s8p, mockPgw := startSgwAndPgw(t, GtpTimeoutForTest)
+ defer mockPgw.Close()
+
+ // ------------------------
+ // ---- Create Session ----
+ csReq := getDefaultCreateSessionRequest(mockPgw.LocalAddr().String())
+
+ // s8_proxy forces a missing IE
+ missingIe := ie.New(ie.BearerContext, 0, nil)
+ mockPgw.SetCreateSessionRequestWithMissingIE(missingIe)
+ csRes, err := s8p.CreateSession(context.Background(), csReq)
+ assert.NoError(t, err)
+ assert.NotEmpty(t, csRes)
+ assert.NotEmpty(t, csRes.GtpError)
+ assert.Equal(t, gtpv2.CauseMandatoryIEMissing, uint8(csRes.GtpError.Cause))
+
+ // check log meesage contains the name of the missing ie
+ assert.Contains(t, csRes.GtpError.Msg, missingIe.Name())
}
func TestS8proxyValidateCreateSession(t *testing.T) {
diff --git a/feg/gateway/services/s8_proxy/servicers/senders.go b/feg/gateway/services/s8_proxy/servicers/senders.go
index 3f645cc7ee3e..a88996812237 100644
--- a/feg/gateway/services/s8_proxy/servicers/senders.go
+++ b/feg/gateway/services/s8_proxy/servicers/senders.go
@@ -38,6 +38,8 @@ func (s *S8Proxy) sendAndReceiveCreateSession(
cPgwUDPAddr.String(), csReq.String())
glog.V(2).Infof("Send Create Session Request (gtp) to %s:\n%s",
cPgwUDPAddr.String(), csReqMsg.(*message.CreateSessionRequest).String())
+ //glog.V(4).Infof("Send Create Session Request (gtp) to %s:\n%s",
+ // cPgwUDPAddr.String(), message.Prettify(csReqMsg))
grpcMessage, err := s.gtpClient.SendMessageAndExtractGrpc(csReq.Imsi, csReq.CAgwTeid, cPgwUDPAddr, csReqMsg)
if err != nil {
@@ -63,6 +65,8 @@ func (s *S8Proxy) sendAndReceiveDeleteSession(req *protos.DeleteSessionRequestPg
dsReqMsg)
glog.V(2).Infof("Send Delete Session Request (gtp) to %s:\n%s",
cPgwUDPAddr.String(), dsReqMsg.(*message.DeleteSessionRequest).String())
+ //glog.V(4).Infof("Send Delete Session Request (gtp) to %s:\n%s",
+ // cPgwUDPAddr.String(), message.Prettify(dsReqMsg))
grpcMessage, err := s.gtpClient.SendMessageAndExtractGrpc(req.Imsi, req.CAgwTeid, cPgwUDPAddr, dsReqMsg)
if err != nil {
return nil, fmt.Errorf("no response message to DeleteSessionRequest: %s", err)
diff --git a/feg/gateway/services/session_proxy/README.md b/feg/gateway/services/session_proxy/README.md
deleted file mode 100644
index 214e2ec61064..000000000000
--- a/feg/gateway/services/session_proxy/README.md
+++ /dev/null
@@ -1,49 +0,0 @@
-# Session Proxy
-
-## Overview of Session Proxy
-Session_proxy is a service from the FEG that interacts with PCRF and OCS. It's main function is to
-translate GRPC messages from sessiond into Diameter protocol back and forth.
-
-## Interfaces
-1. Session Manager (sessiond)
-Magma PCEF is implemented by Session Manager (or sessiond). Session Proxy receive the GRPC messages
-translates from sessiond and translates them into diameter messages for creation (CCR-I and CCA-I),
-update (CCR-U and CCA-U) and termination (CCR-T and CCA-T).
-
-2. PCRF (Gx)
-Session proxy implements Gx interface and will translate policy related calls into diameter AVPs to
-be sent to PCRF. It supports some events like monitoring tracking, time based rules,
-and PCRF initiated messages like reauthentication
-
-3. OCS (Gy)
-Session proxy implements Gy interface and will translate charging related calls into diameter AVPs to
-be sent to OCS. It supports charging reporting and OCS initiated messages like reauthentication
-
-4. PoicyDb
-Session_proxy will get static rules and omnipresent rules from policyDb to inject
-them to the responses back to SessionD
-
-
-##Session Proxy Configuration
-Configuration of Session Proxy can be done through NMS or Swagger API. In both
-cases the configuration of Session Proxy is through Gx and Gy labels/tabs.
-
-
-## Magma PCRF-less configuration
-Omnipresent rules can be used as a way to achieve a PCRF-less (Gx) configuration while
-maintaining charging (Gy) capabilities. Omnipresent rules are configured on Orc8r and injected
-by session proxy to any subscriber that creates a new session. So if those omnipresent rules define a
-Rating Group (or charging key), that key will be used by to charge the user and will
-be communicated through Gy. Note that **all** subscribers will need to have that Rating Group
-configured on OCS so the reporting is tracked.
-
-###Configure Magma PCRF-less:
-- Create omnipresent rules:
-On NMS, create a static rule. In case you want to use charging (Gy) for that rule add a Rating Group
-Then check the box that says `omnipresent`. Once this is enable, any subscriber that attaches to the
-network will get that rule installed. Remember to check that subscriber on OCS too.
-
-- Disable Gx (optional):
-If there is not a PCRF to connect to, you can disable Gx so your session proxy doesn't try to connect to a
-non-existing PCRF. To do so go to swagger API `/feg/{network_id}/gateways/{gateway_id}`
-search for your Federated Gateway(using `feg network` and `feg gateway`) and modify `disableGx` under `Gx` key.
\ No newline at end of file
diff --git a/feg/gateway/services/session_proxy/README.md b/feg/gateway/services/session_proxy/README.md
new file mode 120000
index 000000000000..acabc6089776
--- /dev/null
+++ b/feg/gateway/services/session_proxy/README.md
@@ -0,0 +1 @@
+../../../../docs/readmes/feg/session_proxy.md
\ No newline at end of file
diff --git a/feg/gateway/tools/s6a_cli/main.go b/feg/gateway/tools/s6a_cli/main.go
index 20e8ac719277..89fba08ec030 100644
--- a/feg/gateway/tools/s6a_cli/main.go
+++ b/feg/gateway/tools/s6a_cli/main.go
@@ -24,6 +24,7 @@ import (
"path/filepath"
"strconv"
"strings"
+ "sync"
"time"
"magma/feg/cloud/go/protos"
@@ -48,6 +49,7 @@ const (
var (
cmdRegistry = new(commands.Map)
proxyAddr string
+ remoteS6a bool
mncLen int = 3
s6aAddr string
network string = "sctp"
@@ -61,6 +63,8 @@ var (
eutranVectors int = 3
utranVectors int = 0
useMconfig bool
+ imsiRange uint64 = 1
+ rate int = 0
)
type s6aCli interface {
@@ -99,6 +103,7 @@ func init() {
f.PrintDefaults()
}
f.StringVar(&proxyAddr, "proxy", proxyAddr, "s6a proxy address")
+ f.BoolVar(&remoteS6a, "remote_s6a", remoteS6a, "Use orc8r to get to the s6a_proxy (Run it on AGW without proxy flag)")
f.StringVar(&s6aAddr, "hss_addr", s6aAddr,
"s6a server (HSS) address - overwrites proxy address and starts local s6a proxy")
f.StringVar(&network, "network", network, "s6a server (HSS) network: tcp/sctp")
@@ -117,6 +122,9 @@ func init() {
f.IntVar(&utranVectors, "utran_num", utranVectors, "Number of UTRAN vectors to request")
f.BoolVar(&useMconfig, "use_mconfig", false,
"Use local gateway.mconfig configuration for local proxy (if set - starts local s6a proxy)")
+ f.Uint64Var(&imsiRange, "range", imsiRange, "Send multiple request with consecutive imsis")
+ f.IntVar(&rate, "rate", rate, "Request per second (to be used with range)")
+
}
// AIR Handler
@@ -180,6 +188,7 @@ func air(cmd *commands.Command, args []string) int {
var cli s6aCli
var peerAddr string
if len(s6aAddr) > 0 || useMconfig { // use direct HSS connection if address is provided
+ fmt.Println("Using builtin S6a_proxy")
if useMconfig {
conf = servicers.GetS6aProxyConfigs()
}
@@ -194,6 +203,13 @@ func air(cmd *commands.Command, args []string) int {
cli = s6aBuiltIn{impl: localProxy}
peerAddr = conf.ServerCfg.Addr
} else {
+ if remoteS6a {
+ fmt.Println("Using S6a_proxy through Orc8r")
+ os.Setenv("USE_REMOTE_S6A_PROXY", "true")
+ } else {
+ fmt.Println("Using local S6a_proxy")
+ }
+
cli = s6aProxyCli{}
currAddr, _ := registry.GetServiceAddress(registry.S6A_PROXY)
if currAddr != proxyAddr {
@@ -222,28 +238,72 @@ func air(cmd *commands.Command, args []string) int {
}
peerAddr = proxyAddr
}
- req := &protos.AuthenticationInformationRequest{
- UserName: imsi,
- VisitedPlmn: plmnId[:],
- NumRequestedEutranVectors: uint32(eutranVectors),
- ImmediateResponsePreferred: true,
- NumRequestedUtranGeranVectors: uint32(utranVectors),
- }
- // AIR
- json, err := orcprotos.MarshalIntern(req)
- fmt.Printf("Sending AIR to %s:\n%s\n%+#v\n\n", peerAddr, json, *req)
- r, err := cli.AuthenticationInformation(req)
- if err != nil || r == nil {
- log.Printf("GRPC AIR Error: %v", err)
- return 8
+
+ errChann := make(chan error)
+ airErrors := make([]error, 0)
+ done := make(chan struct{})
+ lenOfImsi := len(imsi)
+ wg := sync.WaitGroup{}
+ // run all the producers in parallel
+ fmt.Printf("Start sending requests %d\n", imsiRange)
+ for i := uint64(0); i < imsiRange; i++ {
+ wg.Add(1)
+ iShadow := i
+ // wait to adjust the rate
+ if rate > 0 && i != 0 && i%uint64(rate) == 0 {
+ fmt.Printf("\nWait 1 sec to send next group of %d request\n\n", rate)
+ time.Sleep(time.Second)
+ }
+ go func() {
+ defer wg.Done()
+ req := &protos.AuthenticationInformationRequest{
+ UserName: fmt.Sprintf("%0*d", lenOfImsi, imsiNum+iShadow),
+ VisitedPlmn: plmnId[:],
+ NumRequestedEutranVectors: uint32(eutranVectors),
+ ImmediateResponsePreferred: true,
+ NumRequestedUtranGeranVectors: uint32(utranVectors),
+ }
+ // AIR
+ json, err := orcprotos.MarshalIntern(req)
+ fmt.Printf("Sending AIR to %s:\n%s\n%+#v\n\n", peerAddr, json, *req)
+ r, err := cli.AuthenticationInformation(req)
+ if err != nil || r == nil {
+ err2 := fmt.Errorf("GRPC AIR Error: %v", err)
+ log.Print(err2)
+ errChann <- err2
+ return
+ }
+ json, err = orcprotos.MarshalIntern(r)
+ if err != nil {
+ err2 := fmt.Errorf("Marshal Error %v for result: %+v", err, *r)
+ errChann <- err2
+ return
+ }
+ fmt.Printf("Received AIA:\n%s\n%+v\n", json, *r)
+ }()
}
- json, err = orcprotos.MarshalIntern(r)
- if err != nil {
- log.Printf("Marshal Error %v for result: %+v", err, *r)
+
+ // go routine to collect the errors
+ go func() {
+ for err2 := range errChann {
+ airErrors = append(airErrors, err2)
+ }
+ done <- struct{}{}
+ }()
+
+ // wait untill all air request are done
+ wg.Wait()
+ close(errChann)
+ // wait until all the errors are processed
+ <-done
+ close(done)
+
+ // check if errors
+ if len(airErrors) != 0 {
+ log.Printf("Errors found: %d request failed out of %d\n", len(airErrors), imsiRange)
return 9
}
- fmt.Printf("Received AIA:\n%s\n%+v\n", json, *r)
-
+ log.Printf("\nAll request (%d) got a response\n", imsiRange)
return 0
}
diff --git a/feg/gateway/tools/s8_cli/main.go b/feg/gateway/tools/s8_cli/main.go
index da4b88324fb9..73753d8a880c 100644
--- a/feg/gateway/tools/s8_cli/main.go
+++ b/feg/gateway/tools/s8_cli/main.go
@@ -38,6 +38,7 @@ import (
var (
cmdRegistry = new(commands.Map)
proxyAddr string
+ remoteS8 bool
IMSI string = "123456789012345"
useMconfig bool
useBuiltinCli bool
@@ -81,6 +82,8 @@ func init() {
csFlags.StringVar(&localPort, "localport", localPort,
"S8 local port to run the server")
+ csFlags.BoolVar(&remoteS8, "remote_s8", remoteS8, "Use orc8r to get to the s0_proxy (Run it on AGW without proxy flag)")
+
csFlags.StringVar(&pgwServerAddr, "server", pgwServerAddr,
"PGW IP:port to send request with format ip:port")
@@ -125,6 +128,8 @@ func init() {
eFlags.BoolVar(&testServer, "test", testServer,
fmt.Sprintf("Start local test s8 server bound to default PGW address (%s)", testServerAddr))
+ eFlags.BoolVar(&remoteS8, "remote_s8", remoteS8, "Use orc8r to get to the s0_proxy (Run it on AGW without proxy flag)")
+
eFlags.StringVar(&localPort, "localport", localPort,
"S8 local port to run the server")
@@ -153,7 +158,7 @@ func createSession(cmd *commands.Command, args []string) int {
if err != nil {
fmt.Println(err)
cmd.Usage()
- return 1
+ return 2
}
// Create Session Request messagea
@@ -229,10 +234,16 @@ func createSession(cmd *commands.Command, args []string) int {
if err != nil {
fmt.Printf("=> Create Session cli command failed: %s\n", err)
- return 9
+ return 3
}
printGRPCMessage("Received GRPC message: ", csRes)
+ // check if message was received but GTP message recived was in fact an error
+ if csRes.GtpError != nil {
+ fmt.Printf("Received a GTP error (see the GRPC message before): %d\n", csRes.GtpError.Cause)
+ return 4
+ }
+
// Delete recently created session (if enableD)
if createDeleteTimeout != -1 {
fmt.Printf("\n=> Sleeping for %ds before deleting....", createDeleteTimeout)
@@ -251,7 +262,7 @@ func createSession(cmd *commands.Command, args []string) int {
dsRes, err := cli.DeleteSession(dsReq)
if err != nil {
fmt.Printf("=> Delete session failed: %s\n", err)
- return 9
+ return 5
}
printGRPCMessage("Received GRPC message: ", dsRes)
}
@@ -315,11 +326,14 @@ func initialize(cmd *commands.Command, args []string) (s8Cli, *flag.FlagSet, err
if err != nil {
return nil, nil, fmt.Errorf("=> BuiltIn S8 Proxy initialization error: %v\n", err)
}
-
cli = s8BuiltIn{localProxy}
} else {
- fmt.Println("Using local S8_proxy")
- // TODO: use local proxy running on the gateway
+ if remoteS8 {
+ fmt.Println("Using S8_proxy through Orc8r")
+ os.Setenv("USE_REMOTE_S8_PROXY", "true")
+ } else {
+ fmt.Println("Using local S8_proxy")
+ }
proxyAddr, _ = registry.GetServiceAddress(registry.S8_PROXY)
cli = s8CliImpl{}
}
diff --git a/feg/protos/s8_proxy.proto b/feg/protos/s8_proxy.proto
index b20533c4e4f2..e3326e947cee 100644
--- a/feg/protos/s8_proxy.proto
+++ b/feg/protos/s8_proxy.proto
@@ -96,8 +96,9 @@ message ServingNetwork {
message BearerContext {
uint32 id = 1;
Fteid user_plane_fteid = 2;
- QosInformation qos = 3;
- uint32 charging_id = 4;
+ bool valid_qos = 3;
+ QosInformation qos = 4;
+ uint32 charging_id = 5;
}
message QosInformation {
@@ -166,5 +167,4 @@ message EchoResponse{
message GtpError {
uint32 cause = 1;
string msg= 2;
-
}
diff --git a/lte/cloud/configs/nprobe.yml b/lte/cloud/configs/nprobe.yml
new file mode 100644
index 000000000000..3878c7114b5f
--- /dev/null
+++ b/lte/cloud/configs/nprobe.yml
@@ -0,0 +1,11 @@
+---
+# Copyright 2020 The Magma Authors.
+
+# This source code is licensed under the BSD-style license found in the
+# LICENSE file in the root directory of this source tree.
+
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
diff --git a/lte/cloud/configs/service_registry.yml b/lte/cloud/configs/service_registry.yml
index 770fa16a90ba..4923c9cd4e0e 100644
--- a/lte/cloud/configs/service_registry.yml
+++ b/lte/cloud/configs/service_registry.yml
@@ -84,3 +84,16 @@ services:
annotations:
orc8r.io/obsidian_handlers_path_prefixes: >
/magma/v1/lte/:network_id/sms,
+
+ nprobe:
+ host: "localhost"
+ port: 9666
+ echo_port: 10088
+ proxy_type: "clientcert"
+ labels:
+ orc8r.io/obsidian_handlers: "true"
+ orc8r.io/swagger_spec: "true"
+ annotations:
+ orc8r.io/obsidian_handlers_path_prefixes: >
+ /magma/v1/lte/:network_id/network_probe/tasks,
+ /magma/v1/lte/:network_id/network_probe/destinations,
diff --git a/lte/cloud/go/lte/const.go b/lte/cloud/go/lte/const.go
index 0ed681c9c36e..486992791c62 100644
--- a/lte/cloud/go/lte/const.go
+++ b/lte/cloud/go/lte/const.go
@@ -63,17 +63,19 @@ const (
NetworkSubscriberConfigType = "network_subscriber_config"
// APNEntityType etc. are configurator network entity types.
- APNEntityType = "apn"
- APNPolicyProfileEntityType = "apn_policy_profile"
- APNResourceEntityType = "apn_resource"
- BaseNameEntityType = "base_name"
- CellularEnodebEntityType = "cellular_enodeb"
- CellularGatewayEntityType = "cellular_gateway"
- CellularGatewayPoolEntityType = "cellular_gateway_pool"
- PolicyQoSProfileEntityType = "policy_qos_profile"
- PolicyRuleEntityType = "policy"
- RatingGroupEntityType = "rating_group"
- SubscriberEntityType = "subscriber"
+ APNEntityType = "apn"
+ APNPolicyProfileEntityType = "apn_policy_profile"
+ APNResourceEntityType = "apn_resource"
+ BaseNameEntityType = "base_name"
+ CellularEnodebEntityType = "cellular_enodeb"
+ CellularGatewayEntityType = "cellular_gateway"
+ CellularGatewayPoolEntityType = "cellular_gateway_pool"
+ PolicyQoSProfileEntityType = "policy_qos_profile"
+ PolicyRuleEntityType = "policy"
+ RatingGroupEntityType = "rating_group"
+ SubscriberEntityType = "subscriber"
+ NetworkProbeTaskEntityType = "network_probe_task"
+ NetworkProbeDestinationEntityType = "network_probe_destination"
// ApnRuleMappingsStreamName etc. are streamer stream names.
ApnRuleMappingsStreamName = "apn_rule_mappings"
diff --git a/lte/cloud/go/protos/pipelined.pb.go b/lte/cloud/go/protos/pipelined.pb.go
index 38cb9138bfda..9a4015e135e6 100644
--- a/lte/cloud/go/protos/pipelined.pb.go
+++ b/lte/cloud/go/protos/pipelined.pb.go
@@ -1077,6 +1077,7 @@ func (m *DeactivateFlowsRequest) GetPolicies() []*VersionedPolicyID {
type RuleModResult struct {
RuleId string `protobuf:"bytes,1,opt,name=rule_id,json=ruleId,proto3" json:"rule_id,omitempty"`
Result RuleModResult_Result `protobuf:"varint,2,opt,name=result,proto3,enum=magma.lte.RuleModResult_Result" json:"result,omitempty"`
+ Version uint64 `protobuf:"varint,3,opt,name=version,proto3" json:"version,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@@ -1121,8 +1122,15 @@ func (m *RuleModResult) GetResult() RuleModResult_Result {
return RuleModResult_SUCCESS
}
+func (m *RuleModResult) GetVersion() uint64 {
+ if m != nil {
+ return m.Version
+ }
+ return 0
+}
+
type ActivateFlowsResult struct {
- DynamicRuleResults []*RuleModResult `protobuf:"bytes,2,rep,name=dynamic_rule_results,json=dynamicRuleResults,proto3" json:"dynamic_rule_results,omitempty"`
+ PolicyResults []*RuleModResult `protobuf:"bytes,2,rep,name=policy_results,json=policyResults,proto3" json:"policy_results,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@@ -1153,9 +1161,9 @@ func (m *ActivateFlowsResult) XXX_DiscardUnknown() {
var xxx_messageInfo_ActivateFlowsResult proto.InternalMessageInfo
-func (m *ActivateFlowsResult) GetDynamicRuleResults() []*RuleModResult {
+func (m *ActivateFlowsResult) GetPolicyResults() []*RuleModResult {
if m != nil {
- return m.DynamicRuleResults
+ return m.PolicyResults
}
return nil
}
@@ -2722,221 +2730,221 @@ func init() {
func init() { proto.RegisterFile("lte/protos/pipelined.proto", fileDescriptor_e17e923ef6f5752e) }
var fileDescriptor_e17e923ef6f5752e = []byte{
- // 3412 bytes of a gzipped FileDescriptorProto
+ // 3423 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x3a, 0x4d, 0x73, 0x1b, 0x47,
- 0x76, 0xc4, 0x07, 0xf1, 0xf1, 0x00, 0x90, 0xa3, 0x96, 0x44, 0x81, 0x94, 0x25, 0x53, 0x63, 0x3b,
- 0xa6, 0x9c, 0x2c, 0x95, 0x70, 0x55, 0xf2, 0xae, 0x9d, 0xca, 0xee, 0x08, 0x33, 0xa0, 0xc6, 0x0b,
- 0x02, 0x50, 0x0f, 0x40, 0xcb, 0x39, 0xa4, 0x6b, 0x38, 0xdd, 0xa0, 0x27, 0x06, 0x66, 0x46, 0x3d,
- 0x03, 0xc9, 0x4a, 0xa5, 0x72, 0xc8, 0x21, 0x87, 0x9c, 0x72, 0x4e, 0x52, 0x95, 0xdf, 0x90, 0x63,
- 0xfe, 0x40, 0x2e, 0x49, 0x55, 0x2e, 0xb9, 0x65, 0xf3, 0x07, 0x52, 0x95, 0xaa, 0x1c, 0xf2, 0x03,
- 0x52, 0xdd, 0x3d, 0x03, 0x0e, 0x40, 0x50, 0x94, 0x6d, 0xe5, 0x84, 0xee, 0xd7, 0xaf, 0x5f, 0xbf,
- 0x7e, 0xdf, 0xaf, 0x07, 0xb0, 0x37, 0x4d, 0xd8, 0xa3, 0x88, 0x87, 0x49, 0x18, 0x3f, 0x8a, 0xfc,
- 0x88, 0x4d, 0xfd, 0x80, 0xd1, 0x43, 0x09, 0x40, 0xf5, 0x99, 0x7b, 0x3e, 0x73, 0x0f, 0xa7, 0x09,
- 0xdb, 0xdb, 0x0d, 0xb9, 0xf7, 0x0b, 0x9e, 0x21, 0x7a, 0xe1, 0x6c, 0x16, 0x06, 0x0a, 0x6b, 0x6f,
- 0x37, 0x4f, 0x21, 0x9c, 0xfa, 0xde, 0x1b, 0x7a, 0x96, 0x2e, 0xed, 0xe7, 0x96, 0x62, 0x16, 0xc7,
- 0x7e, 0x18, 0x90, 0x99, 0x1b, 0xb8, 0xe7, 0x8c, 0xa7, 0x18, 0xf7, 0xf2, 0x18, 0xf3, 0xb3, 0xd8,
- 0xe3, 0xfe, 0x19, 0xe3, 0x19, 0x01, 0xfd, 0x9f, 0x0a, 0x70, 0xc3, 0x61, 0xc9, 0x3c, 0xea, 0x4e,
- 0xc3, 0xd7, 0x31, 0x66, 0x2f, 0xe7, 0x2c, 0x4e, 0xd0, 0x97, 0x50, 0xe3, 0x6a, 0x18, 0xb7, 0x0b,
- 0xfb, 0xa5, 0x83, 0xc6, 0xd1, 0x87, 0x87, 0x0b, 0x56, 0x0f, 0x0d, 0x2f, 0xf1, 0x5f, 0xb9, 0x09,
- 0xcb, 0x6f, 0xc1, 0x8b, 0x0d, 0xe8, 0x16, 0x6c, 0xb2, 0x28, 0xf4, 0xbe, 0x6d, 0x17, 0xf7, 0x0b,
- 0x07, 0x65, 0xac, 0x26, 0xe8, 0x39, 0xb4, 0x5e, 0xce, 0xc3, 0xc4, 0x25, 0xf3, 0x88, 0xba, 0x09,
- 0x8b, 0xdb, 0xa5, 0xfd, 0xc2, 0x41, 0xe3, 0xe8, 0xf7, 0x72, 0x74, 0xc7, 0x72, 0xc5, 0x59, 0x30,
- 0xf9, 0x5c, 0xe0, 0x3b, 0x89, 0x9b, 0xb0, 0xec, 0x90, 0xa6, 0x24, 0xa1, 0xf0, 0x62, 0xfd, 0x77,
- 0xe1, 0xa6, 0x64, 0xdd, 0x64, 0x13, 0x77, 0x3e, 0x4d, 0x32, 0xe6, 0x17, 0xe7, 0x17, 0x72, 0xe7,
- 0xeb, 0x67, 0xe9, 0x3d, 0xc7, 0xd6, 0x89, 0xeb, 0x65, 0xa8, 0x9f, 0x5f, 0xba, 0xe7, 0xdd, 0x3c,
- 0x3f, 0x02, 0x55, 0x5c, 0xf2, 0x1d, 0xef, 0xa8, 0x9f, 0x03, 0x92, 0x67, 0x0c, 0xa5, 0x92, 0xfe,
- 0xff, 0x84, 0xa9, 0xff, 0x79, 0x7a, 0x19, 0x29, 0xa1, 0xec, 0x9c, 0x4b, 0x12, 0x2e, 0xfc, 0x54,
- 0x09, 0x5f, 0x71, 0xfa, 0x5f, 0x15, 0x40, 0xcb, 0xdb, 0x4c, 0x3c, 0x9f, 0x26, 0xe8, 0x0b, 0xa8,
- 0x70, 0x39, 0x92, 0xc7, 0x6e, 0x1d, 0xe9, 0xb9, 0x63, 0x57, 0x91, 0x0f, 0xd5, 0x0f, 0x4e, 0x77,
- 0xe8, 0x4f, 0xa0, 0x92, 0x52, 0x69, 0x40, 0xd5, 0x19, 0x77, 0x3a, 0x96, 0xe3, 0x68, 0x1b, 0x62,
- 0xd2, 0x35, 0xec, 0xde, 0x18, 0x5b, 0x5a, 0x01, 0x21, 0xd8, 0x1a, 0x8c, 0x47, 0xa6, 0x31, 0xb2,
- 0x4c, 0x62, 0x0d, 0x07, 0x9d, 0x67, 0x5a, 0x51, 0x7f, 0x05, 0x37, 0x52, 0xbe, 0x07, 0xdc, 0x3f,
- 0xf7, 0x83, 0xd1, 0x9b, 0x88, 0xa1, 0x2f, 0xa1, 0x9c, 0xbc, 0x89, 0x58, 0xca, 0xc6, 0xa7, 0x39,
- 0x36, 0x2e, 0xe1, 0x1e, 0x5e, 0x0c, 0xb1, 0xdc, 0xa4, 0x7f, 0x0c, 0x90, 0x23, 0x55, 0x81, 0xe2,
- 0xf1, 0x0b, 0x6d, 0x43, 0xfe, 0x7e, 0xa3, 0x15, 0xc4, 0x6f, 0xff, 0xb1, 0x56, 0xd4, 0x4f, 0x61,
- 0xfb, 0x94, 0x71, 0xe1, 0x6c, 0x8c, 0x2a, 0x5d, 0xa3, 0x87, 0x50, 0xe6, 0xf3, 0x29, 0x4b, 0x65,
- 0x7e, 0x3b, 0x77, 0x6a, 0x6a, 0x0c, 0xf3, 0x29, 0xc3, 0x12, 0x05, 0xb5, 0xa1, 0xfa, 0x4a, 0xed,
- 0x96, 0x62, 0x6d, 0xe1, 0x6c, 0xaa, 0xff, 0xb6, 0x04, 0xb7, 0xd6, 0xd9, 0x03, 0x7a, 0x08, 0xa5,
- 0xd8, 0xa7, 0x29, 0xf1, 0x3b, 0x79, 0xc9, 0x2e, 0x54, 0x69, 0x9b, 0x58, 0xe0, 0xa0, 0x3b, 0x50,
- 0xf5, 0x23, 0xe2, 0x52, 0xca, 0x25, 0xf5, 0x3a, 0xae, 0xf8, 0x91, 0x41, 0x29, 0x47, 0x5f, 0x40,
- 0x8b, 0xbe, 0x09, 0xdc, 0x99, 0xef, 0x11, 0xc1, 0x46, 0xdc, 0x2e, 0x4b, 0x5b, 0xbc, 0x82, 0xd5,
- 0x66, 0x8a, 0x2b, 0x26, 0x31, 0xea, 0xc0, 0x56, 0x6a, 0x91, 0x24, 0x94, 0xe2, 0x69, 0x6f, 0x4a,
- 0x56, 0x3e, 0x78, 0x9b, 0x74, 0x71, 0x8b, 0xe7, 0x41, 0xe8, 0x8f, 0xa0, 0xe6, 0x46, 0x01, 0x71,
- 0x67, 0x67, 0xbc, 0x5d, 0x91, 0xdb, 0x3f, 0xca, 0xfb, 0xc1, 0xf9, 0x39, 0x67, 0xe7, 0x6e, 0xc2,
- 0xe8, 0x89, 0xfb, 0xbd, 0x3f, 0x9b, 0xcf, 0x9e, 0xfa, 0x09, 0x17, 0x86, 0x59, 0x75, 0xa3, 0xc0,
- 0x98, 0x9d, 0x71, 0x74, 0x17, 0xea, 0x7e, 0xf4, 0xea, 0x89, 0xba, 0x5b, 0x75, 0xbf, 0x70, 0xd0,
- 0xc4, 0x35, 0x01, 0x90, 0xb7, 0xdb, 0x81, 0xca, 0x2c, 0xf6, 0x63, 0x1a, 0xb4, 0x6b, 0x72, 0x25,
- 0x9d, 0xa1, 0x8f, 0xa0, 0x35, 0x8f, 0xa6, 0x7e, 0xf0, 0x1d, 0x49, 0xe6, 0x41, 0xc0, 0xa6, 0xed,
- 0xba, 0x14, 0x79, 0x53, 0x01, 0x47, 0x12, 0x86, 0x3e, 0x85, 0x6d, 0x1a, 0xbe, 0x0e, 0xf2, 0x68,
- 0x20, 0xd1, 0xb6, 0x32, 0x70, 0x8a, 0xf8, 0x04, 0x6a, 0x32, 0x00, 0xfb, 0x2c, 0x6e, 0x37, 0xa4,
- 0xf8, 0xf6, 0x72, 0x57, 0x58, 0xb1, 0x09, 0xbc, 0xc0, 0xfd, 0xaa, 0x5c, 0x2b, 0x69, 0x65, 0xbd,
- 0x0b, 0x37, 0x56, 0x50, 0x6c, 0x53, 0xe8, 0x4b, 0xa8, 0x83, 0xa4, 0xea, 0xad, 0xe3, 0x8a, 0x98,
- 0xda, 0xf4, 0x2d, 0x66, 0xf2, 0xf7, 0x25, 0xd8, 0x31, 0x99, 0xfb, 0x13, 0x0d, 0x65, 0x17, 0x6a,
- 0xe9, 0xc1, 0x71, 0xbb, 0xb8, 0x5f, 0x3a, 0xa8, 0xe3, 0xaa, 0x3a, 0x79, 0x9d, 0xba, 0x4b, 0x3f,
- 0x5c, 0xdd, 0x39, 0x43, 0x2c, 0x2f, 0x19, 0xe2, 0x92, 0x1e, 0x37, 0x57, 0xf4, 0xf8, 0x4b, 0xd8,
- 0xe5, 0x6c, 0x16, 0xbe, 0x62, 0x84, 0xaa, 0xa8, 0x4e, 0x28, 0x0f, 0x23, 0x32, 0x11, 0x97, 0x94,
- 0x56, 0x53, 0xc3, 0x3b, 0x0a, 0x21, 0x8d, 0xfa, 0x26, 0x0f, 0x55, 0x68, 0xb9, 0xac, 0xea, 0xea,
- 0xbb, 0xa9, 0xba, 0xb6, 0x56, 0xd5, 0xbf, 0xc8, 0xa9, 0xba, 0x2e, 0x55, 0xfd, 0xc1, 0xd5, 0xaa,
- 0xb6, 0xcd, 0x0b, 0x65, 0xeb, 0x7f, 0x5b, 0x80, 0x96, 0x70, 0x9b, 0x93, 0x90, 0xa6, 0x51, 0xed,
- 0x4a, 0x1d, 0x7f, 0xbe, 0x08, 0x9a, 0x45, 0x19, 0xad, 0xf2, 0x89, 0x61, 0x89, 0xc4, 0x6a, 0xc4,
- 0xfc, 0x7c, 0x7d, 0xc4, 0xbc, 0x09, 0xdb, 0x43, 0x03, 0x8f, 0x6c, 0xa3, 0x47, 0x32, 0x60, 0x21,
- 0x1f, 0x46, 0x8b, 0xfa, 0x39, 0xdc, 0x5c, 0x89, 0x30, 0x92, 0xca, 0x57, 0x70, 0x2b, 0x1f, 0x1c,
- 0x88, 0x3a, 0x46, 0x19, 0x46, 0xe3, 0xa8, 0x7d, 0x15, 0x5b, 0x18, 0xe5, 0xc2, 0x84, 0x02, 0x09,
- 0x63, 0x2f, 0x68, 0x45, 0xfd, 0x6f, 0x0a, 0x70, 0xfb, 0x92, 0x91, 0xca, 0xb3, 0x7e, 0xb5, 0x92,
- 0x29, 0xf2, 0x21, 0x7a, 0xed, 0x8e, 0xf7, 0x95, 0x2e, 0xfe, 0xbb, 0x08, 0x8d, 0x5c, 0x3a, 0x47,
- 0x9f, 0xc1, 0xe6, 0xcc, 0x4d, 0xd2, 0x42, 0xa1, 0x71, 0x74, 0x2b, 0xc7, 0x87, 0x40, 0x3b, 0x11,
- 0x6b, 0x58, 0xa1, 0x08, 0x6f, 0x71, 0xa3, 0x88, 0x04, 0xee, 0x8c, 0xa5, 0x71, 0xb5, 0xea, 0x46,
- 0x51, 0xdf, 0x9d, 0x31, 0xb1, 0x74, 0xf6, 0x26, 0x61, 0x31, 0xe1, 0xdf, 0x4b, 0x3f, 0x29, 0xe3,
- 0xaa, 0x9c, 0xe3, 0xef, 0xd1, 0x03, 0x68, 0xc6, 0x8c, 0xbf, 0xf2, 0x3d, 0x46, 0x64, 0x4e, 0x52,
- 0x8e, 0xd0, 0x48, 0x61, 0x32, 0xc7, 0xdc, 0x81, 0x6a, 0xcc, 0x3d, 0x32, 0x73, 0x3d, 0xe9, 0x0b,
- 0x75, 0x5c, 0x89, 0xb9, 0x77, 0xe2, 0x7a, 0x62, 0x81, 0xc6, 0x89, 0x5c, 0xa8, 0xa8, 0x05, 0x1a,
- 0x27, 0x62, 0xe1, 0x09, 0x6c, 0xc6, 0x22, 0x65, 0x4b, 0xfb, 0xde, 0x3a, 0xda, 0x5f, 0x61, 0x3b,
- 0xbd, 0x9d, 0x1c, 0xab, 0xd4, 0xae, 0xd0, 0xf5, 0x10, 0xea, 0x0b, 0x18, 0xd2, 0xa0, 0xd9, 0xed,
- 0x0d, 0xbe, 0x26, 0x1d, 0x6c, 0x09, 0x19, 0x69, 0x1b, 0xe8, 0x43, 0xb8, 0x2b, 0x21, 0x99, 0x01,
- 0x75, 0x7a, 0x86, 0xe3, 0xd8, 0x5d, 0xbb, 0x63, 0x8c, 0xec, 0x41, 0x5f, 0x2b, 0xa0, 0x7b, 0xb0,
- 0x2b, 0x11, 0xba, 0x76, 0xff, 0xf2, 0x72, 0x71, 0x41, 0xd1, 0x7a, 0x31, 0xb4, 0xb1, 0x65, 0x6a,
- 0x25, 0xfd, 0x2f, 0xa0, 0xa9, 0x18, 0x8a, 0xa3, 0x30, 0x88, 0x19, 0x7a, 0xb2, 0xa2, 0xf8, 0xfb,
- 0x97, 0x38, 0x57, 0x88, 0xef, 0x4b, 0xdf, 0xff, 0x56, 0x00, 0x6d, 0xb5, 0x86, 0xfb, 0x81, 0x11,
- 0x72, 0xe6, 0x7a, 0xf9, 0x5c, 0x5a, 0x9d, 0xb9, 0xde, 0x4a, 0xba, 0x29, 0x29, 0xdd, 0xa4, 0xe9,
- 0xe6, 0x3e, 0x34, 0xdc, 0x88, 0x2c, 0x76, 0x29, 0x7d, 0xd7, 0xdd, 0xe8, 0x24, 0xdd, 0x77, 0x07,
- 0xaa, 0x6e, 0x6a, 0x45, 0xa9, 0xb6, 0x5d, 0x65, 0x44, 0x1f, 0xc3, 0x56, 0x44, 0x23, 0x12, 0x27,
- 0x2e, 0x4f, 0x48, 0xe2, 0xcf, 0x98, 0x54, 0x7a, 0x19, 0x37, 0x23, 0x1a, 0x39, 0x02, 0x38, 0xf2,
- 0x67, 0x4c, 0xff, 0x8f, 0x02, 0xdc, 0x5e, 0xa9, 0xde, 0x54, 0xa9, 0xf6, 0x9e, 0xae, 0xd5, 0x85,
- 0x86, 0x2a, 0x1e, 0x95, 0xb9, 0x96, 0xa4, 0x9a, 0x3e, 0x59, 0x4b, 0x2d, 0x77, 0xf8, 0xa1, 0x0c,
- 0xff, 0xa0, 0x76, 0x8a, 0xb1, 0xfe, 0x18, 0xca, 0xd2, 0xb8, 0xb7, 0xa1, 0x71, 0x6a, 0xf4, 0x6c,
- 0x93, 0x3c, 0x1f, 0x0f, 0x46, 0x86, 0xb6, 0x81, 0x9a, 0x50, 0xeb, 0x0f, 0xd2, 0x59, 0x01, 0xb5,
- 0xa0, 0x3e, 0xb2, 0xf0, 0x89, 0xdd, 0x37, 0x46, 0x22, 0x36, 0x11, 0x78, 0x70, 0x6d, 0x81, 0x8a,
- 0xbe, 0x80, 0xea, 0x45, 0x7d, 0x2b, 0x82, 0xd3, 0xfe, 0x75, 0xec, 0xe1, 0x6c, 0x83, 0xce, 0x61,
- 0x7b, 0xe4, 0x9e, 0x4d, 0x99, 0x11, 0xc7, 0xfe, 0x79, 0x30, 0x63, 0x41, 0xb2, 0xe4, 0xd7, 0x85,
- 0x65, 0xbf, 0xbe, 0x07, 0x30, 0x73, 0xfd, 0x80, 0x24, 0x62, 0x4b, 0x5a, 0x01, 0xd7, 0x05, 0x44,
- 0xd2, 0x40, 0x9f, 0xc0, 0x56, 0xec, 0x71, 0x11, 0x1c, 0x14, 0x86, 0xe8, 0x68, 0x4a, 0x07, 0x65,
- 0xdc, 0x4a, 0xa1, 0x12, 0x2b, 0xd6, 0xff, 0x04, 0x6e, 0x1a, 0xd3, 0xe9, 0xca, 0xb1, 0x31, 0x3a,
- 0x86, 0x1b, 0x72, 0x17, 0x71, 0x2f, 0x80, 0xe9, 0x85, 0xf2, 0x25, 0xc5, 0xca, 0x3e, 0xac, 0x25,
- 0x2b, 0x84, 0xf4, 0x2f, 0x45, 0x13, 0xc4, 0x7d, 0x77, 0xea, 0xff, 0x19, 0xa3, 0xf8, 0xcd, 0x7c,
- 0xe8, 0x7a, 0xdf, 0xb1, 0x04, 0x69, 0x50, 0x8a, 0xbe, 0x53, 0x8e, 0xd6, 0xc4, 0x62, 0x88, 0x10,
- 0x94, 0xfd, 0x59, 0xec, 0xa7, 0x2a, 0x97, 0x63, 0xfd, 0x10, 0x6e, 0x28, 0x7c, 0x91, 0x45, 0xe5,
- 0x59, 0xb6, 0xb4, 0x0f, 0xc5, 0x5a, 0x6a, 0x4f, 0x9b, 0xb8, 0x9a, 0xa8, 0x25, 0xfd, 0x7f, 0x0b,
- 0x50, 0xef, 0xc6, 0x33, 0x22, 0x03, 0x0a, 0xfa, 0x79, 0x16, 0x88, 0x94, 0x3b, 0xdf, 0xcb, 0xbb,
- 0x73, 0x86, 0x24, 0x46, 0x4b, 0x51, 0xe8, 0x1f, 0x0b, 0x50, 0xcb, 0x60, 0xc2, 0x6b, 0x1d, 0xcb,
- 0x71, 0xec, 0x41, 0x9f, 0x18, 0x9d, 0x91, 0x7d, 0x6a, 0x69, 0x1b, 0x68, 0x07, 0x50, 0x06, 0x5b,
- 0x18, 0x87, 0xa9, 0x95, 0xd1, 0x03, 0xb8, 0xb7, 0x0a, 0x17, 0x63, 0xa7, 0xf3, 0xcc, 0x32, 0xc7,
- 0x3d, 0xcb, 0xd4, 0x36, 0xd1, 0x2d, 0xd0, 0x32, 0x14, 0x6c, 0xf5, 0x2c, 0xc3, 0xb1, 0x4c, 0xad,
- 0x22, 0x6c, 0x4e, 0x46, 0x39, 0xbb, 0x7f, 0xac, 0x55, 0x45, 0xd4, 0xc8, 0x62, 0x5e, 0x0d, 0x01,
- 0x54, 0xd2, 0x73, 0xeb, 0x02, 0xcd, 0xee, 0xa7, 0x33, 0x10, 0x68, 0x29, 0x09, 0xad, 0xa1, 0xff,
- 0x65, 0x01, 0xc0, 0xa1, 0x93, 0xae, 0x3f, 0x4d, 0x18, 0x8f, 0xd1, 0x43, 0x28, 0x4e, 0x32, 0x57,
- 0xdb, 0x5d, 0x89, 0x61, 0x26, 0x13, 0x06, 0x18, 0x25, 0x21, 0xc7, 0xc5, 0x09, 0x15, 0x6a, 0x48,
- 0x12, 0x4f, 0xca, 0xbc, 0x89, 0xc5, 0x50, 0x40, 0xe2, 0xc8, 0x97, 0xae, 0xd5, 0xc4, 0x62, 0x88,
- 0xb6, 0xa0, 0x38, 0x99, 0xca, 0x50, 0xd1, 0xc4, 0xc5, 0xc9, 0x14, 0xdd, 0x86, 0x4a, 0x4c, 0x27,
- 0x42, 0xfa, 0x9b, 0xb2, 0x32, 0xd9, 0x8c, 0xe9, 0xc4, 0xa6, 0xfa, 0x9f, 0xc2, 0xd6, 0xf2, 0x01,
- 0xe8, 0x67, 0xcb, 0xf9, 0xeb, 0xce, 0xba, 0xfc, 0xd5, 0x67, 0xaf, 0xb3, 0x14, 0xf6, 0x10, 0x2a,
- 0x22, 0xb9, 0xa6, 0xf5, 0xe4, 0xd6, 0xd1, 0x8d, 0x95, 0x2e, 0x34, 0x0c, 0x70, 0x8a, 0xa0, 0xff,
- 0x43, 0x41, 0x85, 0xee, 0x8c, 0x84, 0xb0, 0x09, 0x3f, 0x7a, 0xf5, 0x98, 0xc4, 0xdc, 0xcb, 0xdc,
- 0x44, 0xcc, 0x1d, 0xee, 0x2d, 0x96, 0x68, 0x9c, 0x64, 0xe1, 0x44, 0xcc, 0xcd, 0x38, 0x11, 0x15,
- 0x99, 0x7c, 0x65, 0xf0, 0xc2, 0xe9, 0x45, 0x40, 0xa9, 0xe3, 0x66, 0x06, 0x94, 0x31, 0x62, 0x17,
- 0x6a, 0x22, 0xcf, 0x45, 0x21, 0x4f, 0xa4, 0x10, 0x5a, 0x58, 0xe4, 0xbd, 0x61, 0xc8, 0xa5, 0x73,
- 0x8a, 0xdc, 0x28, 0x97, 0x94, 0x2c, 0x44, 0xae, 0x14, 0x4b, 0xfa, 0xbf, 0x14, 0xa0, 0x89, 0x19,
- 0xf5, 0x39, 0xf3, 0x12, 0x3b, 0x98, 0x84, 0xe8, 0x2b, 0x68, 0x72, 0x46, 0x45, 0x54, 0x23, 0xb9,
- 0xf6, 0xef, 0x60, 0xa9, 0x62, 0xbd, 0x40, 0x5f, 0x4c, 0x44, 0xd8, 0x53, 0xe1, 0x8b, 0x33, 0x6a,
- 0x50, 0x2a, 0x59, 0xfa, 0x1d, 0xd8, 0x16, 0xb4, 0x44, 0x9a, 0x66, 0x3c, 0x1f, 0x28, 0x5b, 0x9c,
- 0x51, 0x47, 0x42, 0xc5, 0x3e, 0xfd, 0x18, 0xb4, 0x55, 0x3a, 0xa8, 0x06, 0x65, 0x7b, 0x78, 0xfa,
- 0x58, 0xdb, 0x48, 0x47, 0x4f, 0xb4, 0x02, 0xaa, 0x42, 0x69, 0x8c, 0x7b, 0x5a, 0x51, 0xd8, 0x9b,
- 0x63, 0x0f, 0xc7, 0xd8, 0xd6, 0x4a, 0x62, 0x2c, 0x10, 0x4f, 0x9f, 0x68, 0x65, 0x51, 0x95, 0x0d,
- 0xe6, 0x09, 0xe3, 0xcf, 0x98, 0x4b, 0x19, 0xef, 0x70, 0xe6, 0x0a, 0x35, 0x08, 0x4b, 0x08, 0x49,
- 0xc2, 0x52, 0x3f, 0x6c, 0xe1, 0xcd, 0x70, 0xc4, 0x7c, 0x8a, 0xf6, 0xa1, 0x79, 0x1e, 0x9c, 0x11,
- 0x29, 0x75, 0x77, 0xc1, 0x1b, 0x9c, 0x07, 0x67, 0x76, 0xf4, 0xea, 0xb1, 0xa1, 0xd2, 0x8c, 0x10,
- 0x1a, 0x09, 0x42, 0x29, 0xf2, 0x16, 0xae, 0x88, 0x69, 0x3f, 0xd4, 0xff, 0x55, 0x78, 0xdf, 0x6b,
- 0x3a, 0x74, 0xb9, 0x3b, 0x13, 0x01, 0x8e, 0x8a, 0x1a, 0xdf, 0x9f, 0xb8, 0x1e, 0x4b, 0x8f, 0xa8,
- 0x0b, 0x88, 0x2d, 0x00, 0xa2, 0x78, 0x09, 0x58, 0x42, 0xfc, 0x20, 0x4e, 0xdc, 0xc0, 0xcb, 0xca,
- 0x9e, 0x46, 0xc0, 0x12, 0x3b, 0x05, 0xa1, 0x3f, 0x04, 0x21, 0x11, 0x29, 0x00, 0xe2, 0x07, 0x93,
- 0x30, 0xed, 0x13, 0xee, 0x5c, 0x21, 0x75, 0xdc, 0xe4, 0x79, 0x95, 0xfd, 0x1a, 0x9a, 0xe1, 0x3c,
- 0xe1, 0xe4, 0x5b, 0xe6, 0x52, 0xe2, 0xa9, 0x6c, 0xd9, 0x58, 0xaa, 0x0a, 0xd6, 0x08, 0x05, 0x83,
- 0xd8, 0x23, 0x60, 0x1d, 0xae, 0x3f, 0x84, 0x9a, 0x39, 0x8f, 0xde, 0xe5, 0x36, 0x22, 0x74, 0x95,
- 0x86, 0xa6, 0x2d, 0x6c, 0x52, 0xd8, 0x94, 0x1f, 0x24, 0x8c, 0xe7, 0x30, 0x9b, 0x31, 0xf7, 0xec,
- 0x0c, 0x26, 0x24, 0x3c, 0x0d, 0x3d, 0x77, 0x4a, 0x26, 0x4a, 0xfc, 0xaa, 0x01, 0x03, 0x09, 0xeb,
- 0x4a, 0x1d, 0xac, 0x0a, 0xa7, 0x74, 0x59, 0x38, 0x7b, 0x50, 0x9f, 0x33, 0x22, 0x7b, 0xa0, 0xac,
- 0x12, 0xa8, 0xce, 0x99, 0x1d, 0x09, 0x05, 0xb5, 0xa1, 0x96, 0x70, 0xc2, 0xa2, 0xcc, 0xcb, 0x9b,
- 0xb8, 0x92, 0x70, 0x2b, 0xb2, 0x29, 0x7a, 0x02, 0x0d, 0xe1, 0xfd, 0x13, 0x15, 0x6b, 0xd2, 0x46,
- 0x39, 0xdf, 0xa4, 0x5f, 0x04, 0x22, 0x0c, 0xf1, 0x45, 0x50, 0xba, 0x0d, 0x15, 0x91, 0xc8, 0x7c,
- 0x2a, 0xcb, 0xc2, 0x3a, 0xde, 0x74, 0xa3, 0xc8, 0xa6, 0xfa, 0x6f, 0x4b, 0xd0, 0x70, 0x58, 0x72,
- 0xcc, 0xc3, 0x79, 0x34, 0x34, 0xb1, 0x40, 0x8b, 0x28, 0x27, 0x17, 0x26, 0x15, 0x51, 0x6e, 0x53,
- 0xf4, 0x21, 0x34, 0x04, 0x38, 0xdf, 0x70, 0x6e, 0x62, 0x88, 0x28, 0x4f, 0x1b, 0x1d, 0x74, 0x1f,
- 0x20, 0xe2, 0xcc, 0x63, 0x94, 0x65, 0xb7, 0x6d, 0xe1, 0x1c, 0x04, 0xfd, 0x3e, 0xd4, 0x05, 0x01,
- 0x95, 0x0f, 0xca, 0xd2, 0xf7, 0x6e, 0xe6, 0x5f, 0x16, 0x28, 0x57, 0x59, 0xa0, 0x16, 0xa5, 0x23,
- 0xb4, 0x0f, 0xa5, 0x88, 0xfa, 0xe9, 0x43, 0xc2, 0x56, 0x1e, 0xd7, 0xb4, 0xb1, 0x58, 0x42, 0x0f,
- 0xa0, 0x15, 0x92, 0x6f, 0x89, 0x68, 0xf7, 0x08, 0x65, 0xb1, 0xaa, 0x83, 0x5b, 0x18, 0xc2, 0x67,
- 0x98, 0xcd, 0x42, 0x11, 0x08, 0xd1, 0x01, 0x68, 0xb2, 0x61, 0x60, 0x24, 0x12, 0x1e, 0x2b, 0x9f,
- 0x60, 0xd4, 0xfd, 0xb7, 0x14, 0x7c, 0xc8, 0x19, 0x15, 0xcd, 0x09, 0x7a, 0x0c, 0x10, 0xb3, 0x84,
- 0x9c, 0x73, 0x32, 0x71, 0xb9, 0xec, 0xf9, 0x1a, 0x47, 0x3b, 0xcb, 0x6f, 0x54, 0x52, 0x48, 0x5d,
- 0x03, 0xe3, 0x5a, 0x2c, 0x26, 0x5d, 0x97, 0xa3, 0xe7, 0x70, 0x93, 0x2e, 0x5a, 0x12, 0xd9, 0x85,
- 0x12, 0xce, 0x5e, 0xca, 0x47, 0x84, 0xc6, 0xd1, 0x83, 0xb7, 0x35, 0x2e, 0xea, 0x39, 0xed, 0x06,
- 0x5d, 0x82, 0x63, 0xf6, 0x12, 0xfd, 0x06, 0x6e, 0x5c, 0x26, 0x08, 0x92, 0xe0, 0xb5, 0xef, 0x82,
- 0xdb, 0x2b, 0xc4, 0xf4, 0x7f, 0x2e, 0x5c, 0xa8, 0xb7, 0x6b, 0x48, 0xf5, 0x4e, 0xdc, 0xbc, 0x7a,
- 0x27, 0xae, 0x50, 0xef, 0xaf, 0xe1, 0xa6, 0x00, 0xab, 0xe8, 0x4e, 0x92, 0x90, 0xb8, 0x51, 0x34,
- 0x7d, 0x23, 0xbb, 0xbb, 0xb5, 0x79, 0x40, 0x9b, 0xb8, 0x5c, 0x0d, 0x47, 0xa1, 0x21, 0x50, 0xd1,
- 0x21, 0xd4, 0x26, 0xaf, 0x29, 0x89, 0x5c, 0x3e, 0x4b, 0x9d, 0x3c, 0xaf, 0xde, 0x2c, 0xa4, 0xe0,
- 0xea, 0x44, 0x8e, 0x66, 0x02, 0x9f, 0xce, 0x05, 0xba, 0x3b, 0x4b, 0xfd, 0x3a, 0x8f, 0x9f, 0x39,
- 0x2d, 0xae, 0xd2, 0xb9, 0x1c, 0xe8, 0x7f, 0x5d, 0x04, 0x70, 0xd4, 0x03, 0xb6, 0xc3, 0x64, 0xe6,
- 0xb8, 0x78, 0xac, 0xbe, 0xe8, 0x9b, 0x9b, 0x17, 0x40, 0x9b, 0xbe, 0x83, 0x97, 0x7e, 0x0a, 0xdb,
- 0xd9, 0xab, 0x78, 0x66, 0xda, 0xca, 0x74, 0xb7, 0x52, 0x70, 0x66, 0xde, 0x9f, 0x41, 0x35, 0x08,
- 0xa9, 0x2c, 0x79, 0x14, 0xb7, 0x79, 0xa1, 0xf4, 0x43, 0xca, 0x6c, 0x13, 0x57, 0x04, 0x86, 0x4d,
- 0x45, 0xdb, 0xa8, 0xcc, 0x7c, 0xf3, 0x72, 0xdb, 0x98, 0x95, 0x3d, 0x69, 0xb5, 0x93, 0xb3, 0xba,
- 0x88, 0xf2, 0x76, 0x45, 0xd6, 0x77, 0xeb, 0xac, 0x6e, 0x68, 0x66, 0x56, 0x37, 0xa4, 0x5c, 0xff,
- 0xcf, 0x02, 0xec, 0x8c, 0x87, 0xdd, 0x54, 0x1e, 0x9d, 0x30, 0x48, 0xd8, 0xf7, 0x89, 0xf2, 0x9a,
- 0x3f, 0x00, 0xf0, 0xdc, 0x79, 0xcc, 0x54, 0xb8, 0x55, 0x89, 0x1f, 0xe5, 0x08, 0x76, 0xc4, 0xa2,
- 0x6d, 0xe1, 0xba, 0xc4, 0x92, 0x61, 0xd6, 0x02, 0x2d, 0x13, 0x42, 0x1c, 0xb8, 0x51, 0xfc, 0x6d,
- 0xa8, 0x12, 0xf5, 0x72, 0xa5, 0x79, 0x71, 0x9e, 0x72, 0xd4, 0x4c, 0x70, 0x4e, 0xba, 0x05, 0xd9,
- 0xb0, 0x3d, 0x71, 0xfd, 0xe9, 0x9c, 0x33, 0x92, 0x3d, 0x66, 0x94, 0x2e, 0xb9, 0x41, 0x57, 0x61,
- 0x08, 0x8f, 0x13, 0x67, 0xf3, 0x99, 0x8a, 0xd9, 0xad, 0x49, 0x0e, 0x4e, 0xf5, 0xbf, 0x2b, 0x43,
- 0x35, 0x65, 0x14, 0xfd, 0x12, 0x6a, 0xe9, 0x85, 0xd8, 0x9a, 0xb6, 0x30, 0xc5, 0x52, 0xbf, 0xa7,
- 0xee, 0x74, 0xce, 0x62, 0x5c, 0x55, 0x57, 0x63, 0xfa, 0xbf, 0x97, 0xa0, 0x91, 0x5b, 0x10, 0x15,
- 0x1c, 0xb6, 0x1c, 0x0b, 0x9f, 0xca, 0x7e, 0xf6, 0x16, 0x68, 0xd8, 0x7a, 0x3e, 0xb6, 0x9c, 0x11,
- 0x31, 0x3a, 0x1d, 0x6b, 0x28, 0x2a, 0xbe, 0x02, 0xba, 0x0f, 0x7b, 0x19, 0x14, 0x5b, 0x5f, 0x59,
- 0x1d, 0xd1, 0x2f, 0xf6, 0x07, 0x04, 0x5b, 0x86, 0x23, 0xbb, 0xd8, 0x7b, 0xb0, 0x9b, 0x95, 0x90,
- 0x9d, 0x41, 0x7f, 0x64, 0xbd, 0x18, 0x91, 0xfe, 0x60, 0x44, 0xba, 0x83, 0x71, 0xdf, 0xd4, 0x4a,
- 0xa8, 0x0d, 0xb7, 0x4e, 0x8c, 0xbe, 0x69, 0x8c, 0x06, 0xf8, 0x1b, 0x62, 0x5b, 0xe4, 0xc4, 0x76,
- 0x1c, 0x51, 0x57, 0x96, 0xd1, 0x1e, 0xec, 0x74, 0x06, 0x7d, 0xd3, 0x16, 0x45, 0xa9, 0xd1, 0xcb,
- 0xaf, 0x6d, 0x8a, 0x32, 0xd7, 0xee, 0xab, 0x46, 0xa8, 0x67, 0xf5, 0x8f, 0x47, 0xcf, 0xb4, 0x8a,
- 0xc0, 0x5f, 0xa2, 0x64, 0xf7, 0x3b, 0x03, 0x8c, 0xad, 0xce, 0x48, 0xab, 0x0a, 0x26, 0x32, 0xfc,
- 0xee, 0x00, 0x7f, 0x6d, 0x60, 0xd3, 0xee, 0x1f, 0x93, 0xe1, 0xa0, 0x67, 0x77, 0xbe, 0xd1, 0x6a,
- 0xe8, 0x63, 0xd8, 0x5f, 0x2c, 0x93, 0x91, 0x65, 0x9b, 0xc4, 0xe8, 0xf5, 0x06, 0xaa, 0x11, 0x27,
- 0x83, 0xa1, 0xec, 0xc7, 0xeb, 0xe8, 0x23, 0xf8, 0xb0, 0x3f, 0x20, 0x96, 0x33, 0x32, 0x9e, 0xf6,
- 0x6c, 0xe7, 0x99, 0x65, 0x92, 0x61, 0xb7, 0x33, 0x24, 0x86, 0xe3, 0x0c, 0x3a, 0xb6, 0x6a, 0xda,
- 0x01, 0x3d, 0x84, 0x4f, 0xf0, 0xb8, 0x67, 0xa9, 0x67, 0x00, 0xb9, 0x1d, 0x93, 0x93, 0x81, 0xb9,
- 0xe8, 0xeb, 0x49, 0xd6, 0x61, 0x37, 0xd0, 0x07, 0xd0, 0x96, 0x04, 0xac, 0xfe, 0x48, 0x70, 0x2c,
- 0xe5, 0x73, 0x6c, 0x39, 0x92, 0x50, 0x53, 0x5c, 0x47, 0x8a, 0xd1, 0x19, 0x8c, 0x71, 0xc7, 0x72,
- 0x88, 0x71, 0x6a, 0xd8, 0x3d, 0xe3, 0x69, 0xcf, 0xd2, 0x5a, 0x68, 0x17, 0x6e, 0x0b, 0xad, 0xd8,
- 0x1d, 0x4b, 0xca, 0xd2, 0x19, 0x0f, 0x87, 0x03, 0x2c, 0xd4, 0xb1, 0x25, 0x1b, 0x80, 0x6f, 0x9c,
- 0x91, 0x75, 0xb2, 0x38, 0x68, 0x5b, 0x7f, 0x0a, 0x3b, 0xeb, 0xcd, 0x08, 0x1d, 0x88, 0x94, 0xc1,
- 0xd3, 0x36, 0x29, 0xef, 0x46, 0x83, 0xc9, 0x84, 0x05, 0xd4, 0x0f, 0xce, 0x6d, 0x4b, 0xa4, 0x0e,
- 0xae, 0xff, 0x57, 0x01, 0x1a, 0x39, 0xa0, 0x48, 0x5f, 0x3e, 0x65, 0x41, 0xe2, 0x4f, 0x7c, 0xc6,
- 0xd3, 0xd8, 0x98, 0x83, 0x5c, 0xfd, 0xd8, 0x8a, 0xbe, 0x86, 0xf6, 0xcb, 0x30, 0x26, 0x4c, 0xb0,
- 0xe1, 0xb1, 0xe5, 0xd7, 0xb1, 0xd2, 0xa5, 0x82, 0x65, 0xcd, 0xdb, 0x1a, 0xbe, 0xfd, 0x32, 0x8c,
- 0x2d, 0xb5, 0x3d, 0xf7, 0x4c, 0x86, 0x9e, 0xc1, 0x36, 0x65, 0x53, 0xf2, 0x92, 0xf1, 0x05, 0x3d,
- 0x15, 0x7a, 0xf6, 0xaf, 0x7b, 0x0f, 0xc3, 0x2d, 0xca, 0xa6, 0xcf, 0x19, 0x4f, 0x29, 0x7d, 0xf6,
- 0x05, 0x54, 0x54, 0xb0, 0x16, 0x25, 0xa7, 0x89, 0x07, 0x43, 0x55, 0x7c, 0x0a, 0xd3, 0xd1, 0x0a,
- 0x62, 0xf4, 0x74, 0xdc, 0xed, 0x6a, 0x45, 0x31, 0xea, 0x0f, 0x3a, 0x43, 0xad, 0x24, 0xf1, 0xc6,
- 0xc3, 0x9e, 0x56, 0xfe, 0xec, 0x67, 0x50, 0xcb, 0x72, 0xb3, 0xe8, 0x79, 0xec, 0xbe, 0x33, 0x32,
- 0x7a, 0x3d, 0x6d, 0x43, 0x94, 0xa7, 0xd8, 0x3a, 0x19, 0x9c, 0x5a, 0x8a, 0x84, 0x6d, 0xf6, 0x2c,
- 0xad, 0x78, 0xf4, 0x3f, 0x75, 0xa8, 0x0f, 0xb3, 0x8f, 0x98, 0xe8, 0x05, 0xdc, 0xc9, 0x7f, 0x80,
- 0x13, 0x81, 0x8a, 0x87, 0xd3, 0xa9, 0x28, 0x47, 0xee, 0xaf, 0x7e, 0xfe, 0x59, 0xfe, 0x48, 0xb7,
- 0x77, 0xf7, 0x2d, 0x9f, 0x87, 0xf4, 0x0d, 0xd4, 0x83, 0x2d, 0x87, 0x25, 0xce, 0x49, 0x16, 0x93,
- 0x62, 0xb4, 0x54, 0x02, 0x2d, 0x12, 0xc5, 0xde, 0x83, 0xb5, 0x21, 0x2c, 0x1f, 0x32, 0xf5, 0x0d,
- 0x34, 0x4c, 0xbf, 0x57, 0xa9, 0xc7, 0x5a, 0xf5, 0x5a, 0x7c, 0x6f, 0x95, 0x81, 0xa5, 0x8f, 0x76,
- 0xd7, 0xf1, 0x87, 0xa1, 0xb5, 0xa4, 0x6a, 0x74, 0x5d, 0xea, 0xde, 0xbb, 0xc6, 0x4a, 0xf4, 0x0d,
- 0xf4, 0x02, 0xb6, 0x57, 0xd4, 0x8d, 0xae, 0xaf, 0x30, 0xf6, 0xae, 0xb5, 0x16, 0x7d, 0x03, 0x19,
- 0xb0, 0x75, 0xcc, 0x12, 0x75, 0xc1, 0x71, 0xec, 0x9e, 0x33, 0x94, 0xa5, 0x37, 0xf9, 0xd1, 0xf9,
- 0xf0, 0x34, 0xf4, 0xe9, 0xde, 0xde, 0xca, 0x23, 0x2f, 0x66, 0x5e, 0xc8, 0xa9, 0x7c, 0x14, 0xd0,
- 0x37, 0xd0, 0xaf, 0x00, 0x64, 0x05, 0x2e, 0x29, 0xa3, 0x9d, 0xf5, 0x6f, 0x8e, 0x7b, 0x77, 0xae,
- 0x78, 0xd1, 0x53, 0x04, 0xb0, 0x7c, 0xb7, 0xff, 0xb1, 0x04, 0x4c, 0xd8, 0x56, 0xef, 0x39, 0xd9,
- 0x23, 0x66, 0xfc, 0x63, 0xa8, 0xf4, 0x61, 0xfb, 0xe2, 0xcb, 0xa9, 0x12, 0xf2, 0x07, 0xab, 0xaa,
- 0xce, 0x7f, 0x55, 0xbd, 0xce, 0x10, 0x18, 0xec, 0x5d, 0xfd, 0x66, 0x85, 0x7e, 0xd0, 0xb7, 0xd7,
- 0x77, 0x61, 0x7b, 0xf1, 0x9c, 0xb9, 0x86, 0xed, 0xfc, 0x97, 0xed, 0xeb, 0xd8, 0xee, 0x42, 0xd3,
- 0xa0, 0x74, 0x41, 0x0d, 0xbd, 0xed, 0xb3, 0xf7, 0xdb, 0xf8, 0xb2, 0x85, 0xcd, 0x4e, 0x59, 0xc2,
- 0xde, 0x0b, 0x29, 0x25, 0x22, 0x7b, 0xd8, 0xb5, 0x5f, 0xfc, 0x24, 0x52, 0xbf, 0x81, 0x9d, 0x63,
- 0x96, 0xac, 0x7b, 0x76, 0x5b, 0x63, 0xf7, 0x4b, 0x8e, 0x79, 0x79, 0xcb, 0xd3, 0xbb, 0x7f, 0xbc,
- 0x2b, 0x11, 0x1e, 0x4d, 0x13, 0xf6, 0xc8, 0x9b, 0x86, 0x73, 0xfa, 0xe8, 0x3c, 0x4c, 0xff, 0x51,
- 0x71, 0x56, 0x91, 0xbf, 0x3f, 0xff, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x19, 0xd6,
- 0xe5, 0x21, 0x00, 0x00,
+ 0x76, 0xc4, 0x07, 0xf1, 0xf1, 0xf0, 0xc1, 0x51, 0x4b, 0xa2, 0x40, 0xca, 0x92, 0xa9, 0xb1, 0x1d,
+ 0x53, 0x4e, 0x96, 0x4a, 0xb8, 0x2a, 0x7a, 0xd7, 0x4e, 0x65, 0x77, 0x04, 0x0c, 0xa8, 0xf1, 0x82,
+ 0x00, 0xd4, 0x03, 0xd0, 0x72, 0x2a, 0x95, 0xae, 0xe1, 0x74, 0x83, 0x9e, 0x18, 0x98, 0x19, 0xf5,
+ 0x0c, 0x28, 0x2b, 0x95, 0xca, 0x21, 0x87, 0x1c, 0x72, 0xca, 0x3d, 0xa9, 0xca, 0x6f, 0x48, 0x55,
+ 0x2e, 0xf9, 0x03, 0xb9, 0x24, 0x55, 0xb9, 0xe4, 0x96, 0xcd, 0x1f, 0x48, 0x55, 0xaa, 0x72, 0xc8,
+ 0x0f, 0x48, 0x75, 0xf7, 0x0c, 0x38, 0x00, 0x41, 0x51, 0x5e, 0x6b, 0x4f, 0xe8, 0x7e, 0xfd, 0xfa,
+ 0xf5, 0xeb, 0xf7, 0xfd, 0x7a, 0x00, 0xbb, 0xd3, 0x98, 0x3d, 0x09, 0x79, 0x10, 0x07, 0xd1, 0x93,
+ 0xd0, 0x0b, 0xd9, 0xd4, 0xf3, 0x19, 0x3d, 0x90, 0x00, 0x54, 0x9d, 0x39, 0xe7, 0x33, 0xe7, 0x60,
+ 0x1a, 0xb3, 0xdd, 0x9d, 0x80, 0xbb, 0x3f, 0xe3, 0x29, 0xa2, 0x1b, 0xcc, 0x66, 0x81, 0xaf, 0xb0,
+ 0x76, 0x77, 0xb2, 0x14, 0x82, 0xa9, 0xe7, 0xbe, 0xa1, 0x67, 0xc9, 0xd2, 0x5e, 0x66, 0x29, 0x62,
+ 0x51, 0xe4, 0x05, 0x3e, 0x99, 0x39, 0xbe, 0x73, 0xce, 0x78, 0x82, 0xf1, 0x20, 0x8b, 0x31, 0x3f,
+ 0x8b, 0x5c, 0xee, 0x9d, 0x31, 0x9e, 0x12, 0xd0, 0xff, 0x39, 0x07, 0xb7, 0x6c, 0x16, 0xcf, 0xc3,
+ 0xee, 0x34, 0x78, 0x1d, 0x61, 0xf6, 0x6a, 0xce, 0xa2, 0x18, 0x7d, 0x09, 0x15, 0xae, 0x86, 0x51,
+ 0x2b, 0xb7, 0x57, 0xd8, 0xaf, 0x1d, 0x7e, 0x78, 0xb0, 0x60, 0xf5, 0xc0, 0x70, 0x63, 0xef, 0xc2,
+ 0x89, 0x59, 0x76, 0x0b, 0x5e, 0x6c, 0x40, 0x77, 0x60, 0x93, 0x85, 0x81, 0xfb, 0x6d, 0x2b, 0xbf,
+ 0x97, 0xdb, 0x2f, 0x62, 0x35, 0x41, 0x2f, 0xa0, 0xf1, 0x6a, 0x1e, 0xc4, 0x0e, 0x99, 0x87, 0xd4,
+ 0x89, 0x59, 0xd4, 0x2a, 0xec, 0xe5, 0xf6, 0x6b, 0x87, 0xbf, 0x97, 0xa1, 0x3b, 0x96, 0x2b, 0xf6,
+ 0x82, 0xc9, 0x17, 0x02, 0xdf, 0x8e, 0x9d, 0x98, 0xa5, 0x87, 0xd4, 0x25, 0x09, 0x85, 0x17, 0xe9,
+ 0xbf, 0x0b, 0xb7, 0x25, 0xeb, 0x1d, 0x36, 0x71, 0xe6, 0xd3, 0x38, 0x65, 0x7e, 0x71, 0x7e, 0x2e,
+ 0x73, 0xbe, 0x7e, 0x96, 0xdc, 0x73, 0x6c, 0x9e, 0x38, 0x6e, 0x8a, 0xfa, 0xf9, 0x95, 0x7b, 0xde,
+ 0xcf, 0xf2, 0x23, 0x50, 0xc5, 0x25, 0xdf, 0xf1, 0x8e, 0xfa, 0x39, 0x20, 0x79, 0xc6, 0x50, 0x2a,
+ 0xe9, 0xb7, 0x27, 0x4c, 0xfd, 0x2f, 0x92, 0xcb, 0x48, 0x09, 0xa5, 0xe7, 0x5c, 0x91, 0x70, 0xee,
+ 0xc7, 0x4a, 0xf8, 0x9a, 0xd3, 0xff, 0x3a, 0x07, 0x5a, 0xd6, 0x66, 0xa2, 0xf9, 0x34, 0x46, 0x5f,
+ 0x40, 0x89, 0xcb, 0x91, 0x3c, 0xb6, 0x79, 0xa8, 0x67, 0x8e, 0x5d, 0x45, 0x3e, 0x50, 0x3f, 0x38,
+ 0xd9, 0xa1, 0x1f, 0x41, 0x29, 0xa1, 0x52, 0x83, 0xb2, 0x3d, 0x6e, 0xb7, 0x4d, 0xdb, 0xd6, 0x36,
+ 0xc4, 0xa4, 0x6b, 0x58, 0xbd, 0x31, 0x36, 0xb5, 0x1c, 0x42, 0xd0, 0x1c, 0x8c, 0x47, 0x1d, 0x63,
+ 0x64, 0x76, 0x88, 0x39, 0x1c, 0xb4, 0x9f, 0x6b, 0x79, 0xfd, 0x02, 0x6e, 0x25, 0x7c, 0x0f, 0xb8,
+ 0x77, 0xee, 0xf9, 0xa3, 0x37, 0x21, 0x43, 0x5f, 0x42, 0x31, 0x7e, 0x13, 0xb2, 0x84, 0x8d, 0x4f,
+ 0x33, 0x6c, 0x5c, 0xc1, 0x3d, 0xb8, 0x1c, 0x62, 0xb9, 0x49, 0xff, 0x18, 0x20, 0x43, 0xaa, 0x04,
+ 0xf9, 0xe3, 0x97, 0xda, 0x86, 0xfc, 0xfd, 0x46, 0xcb, 0x89, 0xdf, 0xfe, 0x53, 0x2d, 0xaf, 0x9f,
+ 0xc2, 0xd6, 0x29, 0xe3, 0xc2, 0xd9, 0x18, 0x55, 0xba, 0x46, 0x8f, 0xa1, 0xc8, 0xe7, 0x53, 0x96,
+ 0xc8, 0xfc, 0x6e, 0xe6, 0xd4, 0xc4, 0x18, 0xe6, 0x53, 0x86, 0x25, 0x0a, 0x6a, 0x41, 0xf9, 0x42,
+ 0xed, 0x96, 0x62, 0x6d, 0xe0, 0x74, 0xaa, 0xff, 0xba, 0x00, 0x77, 0xd6, 0xd9, 0x03, 0x7a, 0x0c,
+ 0x85, 0xc8, 0xa3, 0x09, 0xf1, 0x7b, 0x59, 0xc9, 0x2e, 0x54, 0x69, 0x75, 0xb0, 0xc0, 0x41, 0xf7,
+ 0xa0, 0xec, 0x85, 0xc4, 0xa1, 0x94, 0x4b, 0xea, 0x55, 0x5c, 0xf2, 0x42, 0x83, 0x52, 0x8e, 0xbe,
+ 0x80, 0x06, 0x7d, 0xe3, 0x3b, 0x33, 0xcf, 0x25, 0x82, 0x8d, 0xa8, 0x55, 0x94, 0xb6, 0x78, 0x0d,
+ 0xab, 0xf5, 0x04, 0x57, 0x4c, 0x22, 0xd4, 0x86, 0x66, 0x62, 0x91, 0x24, 0x90, 0xe2, 0x69, 0x6d,
+ 0x4a, 0x56, 0x3e, 0x78, 0x9b, 0x74, 0x71, 0x83, 0x67, 0x41, 0xe8, 0x8f, 0xa0, 0xe2, 0x84, 0x3e,
+ 0x71, 0x66, 0x67, 0xbc, 0x55, 0x92, 0xdb, 0x3f, 0xca, 0xfa, 0xc1, 0xf9, 0x39, 0x67, 0xe7, 0x4e,
+ 0xcc, 0xe8, 0x89, 0xf3, 0xbd, 0x37, 0x9b, 0xcf, 0x9e, 0x79, 0x31, 0x17, 0x86, 0x59, 0x76, 0x42,
+ 0xdf, 0x98, 0x9d, 0x71, 0x74, 0x1f, 0xaa, 0x5e, 0x78, 0x71, 0xa4, 0xee, 0x56, 0xde, 0xcb, 0xed,
+ 0xd7, 0x71, 0x45, 0x00, 0xe4, 0xed, 0xb6, 0xa1, 0x34, 0x8b, 0xbc, 0x88, 0xfa, 0xad, 0x8a, 0x5c,
+ 0x49, 0x66, 0xe8, 0x23, 0x68, 0xcc, 0xc3, 0xa9, 0xe7, 0x7f, 0x47, 0xe2, 0xb9, 0xef, 0xb3, 0x69,
+ 0xab, 0x2a, 0x45, 0x5e, 0x57, 0xc0, 0x91, 0x84, 0xa1, 0x4f, 0x61, 0x8b, 0x06, 0xaf, 0xfd, 0x2c,
+ 0x1a, 0x48, 0xb4, 0x66, 0x0a, 0x4e, 0x10, 0x8f, 0xa0, 0x22, 0x03, 0xb0, 0xc7, 0xa2, 0x56, 0x4d,
+ 0x8a, 0x6f, 0x37, 0x73, 0x85, 0x15, 0x9b, 0xc0, 0x0b, 0xdc, 0xaf, 0x8a, 0x95, 0x82, 0x56, 0xd4,
+ 0xbb, 0x70, 0x6b, 0x05, 0xc5, 0xea, 0x08, 0x7d, 0x09, 0x75, 0x90, 0x44, 0xbd, 0x55, 0x5c, 0x12,
+ 0x53, 0x8b, 0xbe, 0xc5, 0x4c, 0xfe, 0xbe, 0x00, 0xdb, 0x1d, 0xe6, 0xfc, 0x48, 0x43, 0xd9, 0x81,
+ 0x4a, 0x72, 0x70, 0xd4, 0xca, 0xef, 0x15, 0xf6, 0xab, 0xb8, 0xac, 0x4e, 0x5e, 0xa7, 0xee, 0xc2,
+ 0x0f, 0x57, 0x77, 0xc6, 0x10, 0x8b, 0x4b, 0x86, 0xb8, 0xa4, 0xc7, 0xcd, 0x15, 0x3d, 0xfe, 0x1c,
+ 0x76, 0x38, 0x9b, 0x05, 0x17, 0x8c, 0x50, 0x15, 0xd5, 0x09, 0xe5, 0x41, 0x48, 0x26, 0xe2, 0x92,
+ 0xd2, 0x6a, 0x2a, 0x78, 0x5b, 0x21, 0x24, 0x51, 0xbf, 0xc3, 0x03, 0x15, 0x5a, 0xae, 0xaa, 0xba,
+ 0xfc, 0x6e, 0xaa, 0xae, 0xac, 0x55, 0xf5, 0xcf, 0x32, 0xaa, 0xae, 0x4a, 0x55, 0x7f, 0x70, 0xbd,
+ 0xaa, 0xad, 0xce, 0xa5, 0xb2, 0xf5, 0x7f, 0xca, 0x41, 0x43, 0xb8, 0xcd, 0x49, 0x40, 0x93, 0xa8,
+ 0x76, 0xad, 0x8e, 0x3f, 0x5f, 0x04, 0xcd, 0xbc, 0x8c, 0x56, 0xd9, 0xc4, 0xb0, 0x44, 0x62, 0x25,
+ 0x62, 0x66, 0x8d, 0xa3, 0x20, 0x43, 0xf3, 0xc2, 0x38, 0x3e, 0x5f, 0x1f, 0x4b, 0x6f, 0xc3, 0xd6,
+ 0xd0, 0xc0, 0x23, 0xcb, 0xe8, 0x91, 0x14, 0x98, 0xcb, 0x06, 0xd8, 0xbc, 0xfe, 0x27, 0x70, 0x7b,
+ 0x25, 0xf6, 0x48, 0x2a, 0xbf, 0x80, 0xa6, 0xaa, 0x39, 0x88, 0x3a, 0x5a, 0x19, 0x4b, 0xed, 0xb0,
+ 0x75, 0x1d, 0xab, 0xb8, 0x11, 0x26, 0xe9, 0x4f, 0xa2, 0x7f, 0x55, 0xac, 0xe4, 0xb4, 0xbc, 0xfe,
+ 0xb7, 0x39, 0xb8, 0x7b, 0xc5, 0x66, 0x93, 0x03, 0x96, 0x13, 0x47, 0x36, 0x62, 0xaf, 0xdd, 0xf1,
+ 0xbe, 0xb2, 0xc7, 0xff, 0xe4, 0xa1, 0x96, 0xc9, 0xee, 0xe8, 0x33, 0xd8, 0x9c, 0x39, 0x71, 0x52,
+ 0x37, 0xd4, 0x0e, 0xef, 0x64, 0xf8, 0x10, 0x68, 0x27, 0x62, 0x0d, 0x2b, 0x14, 0xe1, 0x3c, 0x4e,
+ 0x18, 0x12, 0xdf, 0x99, 0xb1, 0x24, 0xcc, 0x96, 0x9d, 0x30, 0xec, 0x3b, 0x33, 0x26, 0x96, 0xce,
+ 0xde, 0xc4, 0x2c, 0x22, 0xfc, 0xfb, 0x54, 0x37, 0x72, 0x8e, 0xbf, 0x47, 0x8f, 0xa0, 0x1e, 0x31,
+ 0x7e, 0xe1, 0xb9, 0x8c, 0xc8, 0x14, 0xa5, 0xfc, 0xa2, 0x96, 0xc0, 0x64, 0xca, 0xb9, 0x07, 0xe5,
+ 0x88, 0xbb, 0x64, 0xe6, 0xb8, 0xd2, 0x35, 0xaa, 0xb8, 0x14, 0x71, 0xf7, 0xc4, 0x71, 0xc5, 0x02,
+ 0x8d, 0x62, 0xb9, 0x50, 0x52, 0x0b, 0x34, 0x8a, 0xc5, 0xc2, 0x11, 0x6c, 0x46, 0x22, 0x83, 0x4b,
+ 0x73, 0x6f, 0x1e, 0xee, 0xad, 0xb0, 0x9d, 0xdc, 0x4e, 0x8e, 0x55, 0xa6, 0x57, 0xe8, 0x7a, 0x00,
+ 0xd5, 0x05, 0x0c, 0x69, 0x50, 0xef, 0xf6, 0x06, 0x5f, 0x93, 0x36, 0x36, 0x85, 0x8c, 0xb4, 0x0d,
+ 0xf4, 0x21, 0xdc, 0x97, 0x90, 0xd4, 0x6a, 0xda, 0x3d, 0xc3, 0xb6, 0xad, 0xae, 0xd5, 0x36, 0x46,
+ 0xd6, 0xa0, 0xaf, 0xe5, 0xd0, 0x03, 0xd8, 0x91, 0x08, 0x5d, 0xab, 0x7f, 0x75, 0x39, 0xbf, 0xa0,
+ 0x68, 0xbe, 0x1c, 0x5a, 0xd8, 0xec, 0x68, 0x05, 0xfd, 0x2f, 0xa1, 0xae, 0x18, 0x8a, 0xc2, 0xc0,
+ 0x8f, 0x18, 0x3a, 0x5a, 0x51, 0xfc, 0xc3, 0x2b, 0x9c, 0x2b, 0xc4, 0xf7, 0xa5, 0xef, 0x7f, 0xcf,
+ 0x81, 0xb6, 0x5a, 0xd2, 0xfd, 0xc0, 0x80, 0x39, 0x73, 0xdc, 0x6c, 0x6a, 0x2d, 0xcf, 0x1c, 0x77,
+ 0x25, 0xfb, 0x14, 0x94, 0x6e, 0x92, 0xec, 0xf3, 0x10, 0x6a, 0x4e, 0x48, 0x16, 0xbb, 0x94, 0xbe,
+ 0xab, 0x4e, 0x78, 0x92, 0xec, 0xbb, 0x07, 0x65, 0x27, 0xb1, 0xa2, 0x44, 0xdb, 0x8e, 0x32, 0xa2,
+ 0x8f, 0xa1, 0x19, 0xd2, 0x90, 0x44, 0xb1, 0xc3, 0x63, 0x12, 0x7b, 0x33, 0x26, 0x95, 0x5e, 0xc4,
+ 0xf5, 0x90, 0x86, 0xb6, 0x00, 0x8e, 0xbc, 0x19, 0xd3, 0xff, 0x33, 0x07, 0x77, 0x57, 0x8a, 0x39,
+ 0x55, 0xb9, 0xbd, 0xa7, 0x6b, 0x75, 0xa1, 0xa6, 0x6a, 0x49, 0x65, 0xae, 0x05, 0xa9, 0xa6, 0x4f,
+ 0xd6, 0x52, 0xcb, 0x1c, 0x7e, 0x20, 0xb3, 0x01, 0xa8, 0x9d, 0x62, 0xac, 0x3f, 0x85, 0xa2, 0x34,
+ 0xee, 0x2d, 0xa8, 0x9d, 0x1a, 0x3d, 0xab, 0x43, 0x5e, 0x8c, 0x07, 0x23, 0x43, 0xdb, 0x40, 0x75,
+ 0xa8, 0xf4, 0x07, 0xc9, 0x2c, 0x87, 0x1a, 0x50, 0x1d, 0x99, 0xf8, 0xc4, 0xea, 0x1b, 0x23, 0x11,
+ 0x90, 0x08, 0x3c, 0xba, 0xb1, 0x5e, 0x45, 0x5f, 0x40, 0xf9, 0xb2, 0xdc, 0x15, 0x71, 0x69, 0xef,
+ 0x26, 0xf6, 0x70, 0xba, 0x41, 0xe7, 0xb0, 0x35, 0x72, 0xce, 0xa6, 0xcc, 0x88, 0x22, 0xef, 0xdc,
+ 0x9f, 0x31, 0x3f, 0x5e, 0xf2, 0xeb, 0xdc, 0xb2, 0x5f, 0x3f, 0x00, 0x98, 0x39, 0x9e, 0x4f, 0x62,
+ 0xb1, 0x25, 0x29, 0x88, 0xab, 0x02, 0x22, 0x69, 0xa0, 0x4f, 0xa0, 0x19, 0xb9, 0x5c, 0x04, 0x07,
+ 0x85, 0x21, 0x1a, 0x9c, 0xc2, 0x7e, 0x11, 0x37, 0x12, 0xa8, 0xc4, 0x8a, 0xf4, 0x3f, 0x85, 0xdb,
+ 0xc6, 0x74, 0xba, 0x72, 0x6c, 0x84, 0x8e, 0xe1, 0x96, 0xdc, 0x45, 0x9c, 0x4b, 0x60, 0x72, 0xa1,
+ 0x6c, 0x85, 0xb1, 0xb2, 0x0f, 0x6b, 0xf1, 0x0a, 0x21, 0xfd, 0x4b, 0xd1, 0x13, 0x71, 0xcf, 0x99,
+ 0x7a, 0x7f, 0xce, 0x28, 0x7e, 0x33, 0x1f, 0x3a, 0xee, 0x77, 0x2c, 0x46, 0x1a, 0x14, 0xc2, 0xef,
+ 0x94, 0xa3, 0xd5, 0xb1, 0x18, 0x22, 0x04, 0x45, 0x6f, 0x16, 0x79, 0x89, 0xca, 0xe5, 0x58, 0x3f,
+ 0x80, 0x5b, 0x0a, 0x5f, 0x24, 0x55, 0x79, 0x96, 0x25, 0xed, 0x43, 0xb1, 0x96, 0xd8, 0xd3, 0x26,
+ 0x2e, 0xc7, 0x6a, 0x49, 0xff, 0xbf, 0x1c, 0x54, 0xbb, 0xd1, 0x8c, 0xc8, 0x80, 0x82, 0x7e, 0x9a,
+ 0x06, 0x22, 0xe5, 0xce, 0x0f, 0xb2, 0xee, 0x9c, 0x22, 0x89, 0xd1, 0x52, 0x14, 0xfa, 0xc7, 0x1c,
+ 0x54, 0x52, 0x98, 0xf0, 0x5a, 0xdb, 0xb4, 0x6d, 0x6b, 0xd0, 0x27, 0x46, 0x7b, 0x64, 0x9d, 0x9a,
+ 0xda, 0x06, 0xda, 0x06, 0x94, 0xc2, 0x16, 0xc6, 0xd1, 0xd1, 0x8a, 0xe8, 0x11, 0x3c, 0x58, 0x85,
+ 0x8b, 0xb1, 0xdd, 0x7e, 0x6e, 0x76, 0xc6, 0x3d, 0xb3, 0xa3, 0x6d, 0xa2, 0x3b, 0xa0, 0xa5, 0x28,
+ 0xd8, 0xec, 0x99, 0x86, 0x6d, 0x76, 0xb4, 0x92, 0xb0, 0x39, 0x19, 0xe5, 0xac, 0xfe, 0xb1, 0x56,
+ 0x16, 0x51, 0x23, 0x8d, 0x79, 0x15, 0x04, 0x50, 0x4a, 0xce, 0xad, 0x0a, 0x34, 0xab, 0x9f, 0xcc,
+ 0x40, 0xa0, 0x25, 0x24, 0xb4, 0x9a, 0xfe, 0x57, 0x39, 0x00, 0x9b, 0x4e, 0xba, 0xde, 0x34, 0x66,
+ 0x3c, 0x42, 0x8f, 0x21, 0x3f, 0x49, 0x5d, 0x6d, 0x67, 0x25, 0x86, 0x75, 0x98, 0x30, 0xc0, 0x30,
+ 0x0e, 0x38, 0xce, 0x4f, 0xa8, 0x50, 0x43, 0x1c, 0xbb, 0x52, 0xe6, 0x75, 0x2c, 0x86, 0x02, 0x12,
+ 0x85, 0x9e, 0x74, 0xad, 0x3a, 0x16, 0x43, 0xd4, 0x84, 0xfc, 0x64, 0x2a, 0x43, 0x45, 0x1d, 0xe7,
+ 0x27, 0x53, 0x74, 0x17, 0x4a, 0x11, 0x9d, 0x08, 0xe9, 0x6f, 0xca, 0x42, 0x65, 0x33, 0xa2, 0x13,
+ 0x8b, 0xea, 0x7f, 0x06, 0xcd, 0xe5, 0x03, 0xd0, 0x4f, 0x96, 0xf3, 0xd7, 0xbd, 0x75, 0xf9, 0xab,
+ 0xcf, 0x5e, 0xa7, 0x29, 0xec, 0x31, 0x94, 0x44, 0x72, 0x4d, 0xca, 0xcb, 0xe6, 0xe1, 0xad, 0x95,
+ 0xa6, 0x34, 0xf0, 0x71, 0x82, 0xa0, 0xff, 0x43, 0x4e, 0x85, 0xee, 0x94, 0x84, 0xb0, 0x09, 0x2f,
+ 0xbc, 0x78, 0x4a, 0x22, 0xee, 0xa6, 0x6e, 0x22, 0xe6, 0x36, 0x77, 0x17, 0x4b, 0x34, 0x8a, 0xd3,
+ 0x70, 0x22, 0xe6, 0x9d, 0x28, 0x16, 0x05, 0x9a, 0x7c, 0x74, 0x70, 0x83, 0xe9, 0x65, 0x40, 0xa9,
+ 0xe2, 0x7a, 0x0a, 0x94, 0x31, 0x62, 0x07, 0x2a, 0x22, 0xcf, 0x85, 0x01, 0x8f, 0xa5, 0x10, 0x1a,
+ 0x58, 0xe4, 0xbd, 0x61, 0xc0, 0xa5, 0x73, 0x8a, 0xdc, 0x28, 0x97, 0x94, 0x2c, 0x44, 0xae, 0x14,
+ 0x4b, 0xfa, 0xbf, 0xe6, 0xa0, 0x8e, 0x19, 0xf5, 0x38, 0x73, 0x63, 0xcb, 0x9f, 0x04, 0xe8, 0x2b,
+ 0xa8, 0x73, 0x46, 0x45, 0x54, 0x23, 0x99, 0x6e, 0x70, 0x7f, 0xa9, 0x80, 0xbd, 0x44, 0x5f, 0x4c,
+ 0x44, 0xd8, 0x53, 0xe1, 0x8b, 0x33, 0x6a, 0x50, 0x2a, 0x59, 0xfa, 0x1d, 0xd8, 0x12, 0xb4, 0x44,
+ 0x9a, 0x66, 0x3c, 0x1b, 0x28, 0x1b, 0x9c, 0x51, 0x5b, 0x42, 0xc5, 0x3e, 0xfd, 0x18, 0xb4, 0x55,
+ 0x3a, 0xa8, 0x02, 0x45, 0x6b, 0x78, 0xfa, 0x54, 0xdb, 0x48, 0x46, 0x47, 0x5a, 0x0e, 0x95, 0xa1,
+ 0x30, 0xc6, 0x3d, 0x2d, 0x2f, 0xec, 0xcd, 0xb6, 0x86, 0x63, 0x6c, 0x69, 0x05, 0x31, 0x16, 0x88,
+ 0xa7, 0x47, 0x5a, 0x51, 0x3f, 0x87, 0xdb, 0x83, 0x79, 0xcc, 0xf8, 0x73, 0xe6, 0x50, 0xc6, 0xdb,
+ 0x9c, 0x39, 0x42, 0x0d, 0xc2, 0x12, 0x02, 0x12, 0xb3, 0xc4, 0x0f, 0x1b, 0x78, 0x33, 0x18, 0x31,
+ 0x8f, 0xa2, 0x3d, 0xa8, 0x9f, 0xfb, 0x67, 0x44, 0x4a, 0xdd, 0x59, 0xf0, 0x06, 0xe7, 0xfe, 0x99,
+ 0x15, 0x5e, 0x3c, 0x35, 0x54, 0x9a, 0x11, 0x42, 0x23, 0x7e, 0x20, 0x45, 0xde, 0xc0, 0x25, 0x31,
+ 0xed, 0x07, 0xfa, 0xbf, 0x09, 0xef, 0x7b, 0x4d, 0x87, 0x0e, 0x77, 0x66, 0x22, 0xc0, 0x51, 0x51,
+ 0xf2, 0x7b, 0x13, 0xc7, 0x65, 0xc9, 0x11, 0x55, 0x01, 0xb1, 0x04, 0x40, 0x14, 0x2f, 0x3e, 0x8b,
+ 0x89, 0xe7, 0x47, 0xb1, 0xe3, 0xbb, 0x69, 0xd9, 0x53, 0xf3, 0x59, 0x6c, 0x25, 0x20, 0xf4, 0x87,
+ 0x20, 0x24, 0x22, 0x05, 0x40, 0x3c, 0x7f, 0x12, 0x24, 0x6d, 0xc3, 0xbd, 0x6b, 0xa4, 0x8e, 0xeb,
+ 0x3c, 0xab, 0xb2, 0x5f, 0x42, 0x3d, 0x98, 0xc7, 0x9c, 0x7c, 0xcb, 0x1c, 0x4a, 0x5c, 0x95, 0x2d,
+ 0x6b, 0x4b, 0x55, 0xc1, 0x1a, 0xa1, 0x60, 0x10, 0x7b, 0x04, 0xac, 0xcd, 0xf5, 0xc7, 0x50, 0xe9,
+ 0xcc, 0xc3, 0x77, 0xb9, 0x8d, 0x08, 0x5d, 0x85, 0x61, 0xc7, 0x12, 0x36, 0x29, 0x6c, 0xca, 0xf3,
+ 0x63, 0xc6, 0x33, 0x98, 0xf5, 0x88, 0xbb, 0x56, 0x0a, 0x13, 0x12, 0x9e, 0x06, 0xae, 0x33, 0x25,
+ 0x13, 0x25, 0x7e, 0xd5, 0x8f, 0x81, 0x84, 0x75, 0xa5, 0x0e, 0x56, 0x85, 0x53, 0xb8, 0x2a, 0x9c,
+ 0x5d, 0xa8, 0xce, 0x19, 0x91, 0x2d, 0x51, 0x5a, 0x09, 0x94, 0xe7, 0xcc, 0x0a, 0x85, 0x82, 0x5a,
+ 0x50, 0x89, 0x39, 0x61, 0x61, 0xea, 0xe5, 0x75, 0x5c, 0x8a, 0xb9, 0x19, 0x5a, 0x14, 0x1d, 0x41,
+ 0x4d, 0x78, 0xff, 0x44, 0xc5, 0x9a, 0xa4, 0x6f, 0xce, 0xf6, 0xec, 0x97, 0x81, 0x08, 0x43, 0x74,
+ 0x19, 0x94, 0xee, 0x42, 0x49, 0x24, 0x32, 0x8f, 0xca, 0xb2, 0xb0, 0x8a, 0x37, 0x9d, 0x30, 0xb4,
+ 0xa8, 0xfe, 0xeb, 0x02, 0xd4, 0x6c, 0x16, 0x1f, 0xf3, 0x60, 0x1e, 0x0e, 0x3b, 0x58, 0xa0, 0x85,
+ 0x94, 0x93, 0x4b, 0x93, 0x0a, 0x29, 0xb7, 0x28, 0xfa, 0x10, 0x6a, 0x02, 0x9c, 0xed, 0x3f, 0x37,
+ 0x31, 0x84, 0x94, 0x27, 0x7d, 0x0f, 0x7a, 0x08, 0x10, 0x72, 0xe6, 0x32, 0xca, 0xd2, 0xdb, 0x36,
+ 0x70, 0x06, 0x82, 0x7e, 0x1f, 0xaa, 0x82, 0x80, 0xca, 0x07, 0x45, 0xe9, 0x7b, 0xb7, 0xb3, 0x0f,
+ 0x0d, 0x94, 0xab, 0x2c, 0x50, 0x09, 0x93, 0x11, 0xda, 0x83, 0x42, 0x48, 0xbd, 0xe4, 0x5d, 0xa1,
+ 0x99, 0xc5, 0xed, 0x58, 0x58, 0x2c, 0xa1, 0x47, 0xd0, 0x08, 0xc8, 0xb7, 0x44, 0x74, 0x7f, 0x84,
+ 0xb2, 0x48, 0xd5, 0xc1, 0x0d, 0x0c, 0xc1, 0x73, 0xcc, 0x66, 0x81, 0x08, 0x84, 0x68, 0x1f, 0x34,
+ 0xd9, 0x30, 0x30, 0x12, 0x0a, 0x8f, 0x95, 0x2f, 0x32, 0xea, 0xfe, 0x4d, 0x05, 0x1f, 0x72, 0x46,
+ 0x45, 0xb7, 0x82, 0x9e, 0x02, 0x44, 0x2c, 0x26, 0xe7, 0x9c, 0x4c, 0x1c, 0x2e, 0x5b, 0xc0, 0xda,
+ 0xe1, 0xf6, 0xf2, 0x93, 0x95, 0x14, 0x52, 0xd7, 0xc0, 0xb8, 0x12, 0x89, 0x49, 0xd7, 0xe1, 0xe8,
+ 0x05, 0xdc, 0xa6, 0x8b, 0x96, 0x44, 0x36, 0xa5, 0x84, 0xb3, 0x57, 0xf2, 0x4d, 0xa1, 0x76, 0xf8,
+ 0xe8, 0x6d, 0x8d, 0x8b, 0x7a, 0x5d, 0xbb, 0x45, 0x97, 0xe0, 0x98, 0xbd, 0x42, 0xbf, 0x82, 0x5b,
+ 0x57, 0x09, 0x82, 0x24, 0x78, 0xe3, 0x33, 0xe1, 0xd6, 0x0a, 0x31, 0xfd, 0x5f, 0x72, 0x97, 0xea,
+ 0xed, 0x1a, 0x52, 0xbd, 0x13, 0x27, 0xab, 0xde, 0x89, 0x23, 0xd4, 0xfb, 0x4b, 0xb8, 0x2d, 0xc0,
+ 0x2a, 0xba, 0x93, 0x38, 0x20, 0x4e, 0x18, 0x4e, 0xdf, 0xc8, 0xc6, 0x6e, 0x6d, 0x1e, 0xd0, 0x26,
+ 0x0e, 0x57, 0xc3, 0x51, 0x60, 0x08, 0x54, 0x74, 0x00, 0x95, 0xc9, 0x6b, 0x4a, 0x42, 0x87, 0xcf,
+ 0x12, 0x27, 0xcf, 0xaa, 0x37, 0x0d, 0x29, 0xb8, 0x3c, 0x91, 0xa3, 0x99, 0xc0, 0xa7, 0x73, 0x81,
+ 0xee, 0xcc, 0x12, 0xbf, 0xce, 0xe2, 0xa7, 0x4e, 0x8b, 0xcb, 0x74, 0x2e, 0x07, 0xfa, 0xdf, 0xe4,
+ 0x01, 0x6c, 0xf5, 0x9e, 0x6d, 0x33, 0x99, 0x39, 0x2e, 0xdf, 0xae, 0x2f, 0xdb, 0xe8, 0xfa, 0x25,
+ 0xd0, 0xa2, 0xef, 0xe0, 0xa5, 0x9f, 0xc2, 0x56, 0xfa, 0x48, 0x9e, 0xed, 0x9e, 0x1b, 0xb8, 0x99,
+ 0x80, 0x53, 0xf3, 0xfe, 0x0c, 0xca, 0x7e, 0x40, 0x65, 0xc9, 0xa3, 0xb8, 0xcd, 0x0a, 0xa5, 0x1f,
+ 0x50, 0x66, 0x75, 0x70, 0x49, 0x60, 0x58, 0x54, 0xb4, 0x8d, 0xca, 0xcc, 0x37, 0xaf, 0xb6, 0x8d,
+ 0x69, 0xd9, 0x93, 0x54, 0x3b, 0x19, 0xab, 0x0b, 0x29, 0x6f, 0x95, 0x64, 0x7d, 0xb7, 0xce, 0xea,
+ 0x86, 0x9d, 0xd4, 0xea, 0x86, 0x94, 0xeb, 0xff, 0x95, 0x83, 0xed, 0xf1, 0xb0, 0x9b, 0xc8, 0xa3,
+ 0x1d, 0xf8, 0x31, 0xfb, 0x3e, 0x56, 0x5e, 0xf3, 0x07, 0x00, 0xae, 0x33, 0x8f, 0x98, 0x0a, 0xb7,
+ 0x2a, 0xf1, 0xa3, 0x0c, 0xc1, 0xb6, 0x58, 0xb4, 0x4c, 0x5c, 0x95, 0x58, 0x32, 0xcc, 0x9a, 0xa0,
+ 0xa5, 0x42, 0x88, 0x7c, 0x27, 0x8c, 0xbe, 0x0d, 0x54, 0xa2, 0x5e, 0xae, 0x34, 0x2f, 0xcf, 0x53,
+ 0x8e, 0x9a, 0x0a, 0xce, 0x4e, 0xb6, 0x20, 0x0b, 0xb6, 0x26, 0x8e, 0x37, 0x9d, 0x73, 0x46, 0xd2,
+ 0xb7, 0x8d, 0xc2, 0x15, 0x37, 0xe8, 0x2a, 0x0c, 0xe1, 0x71, 0xe2, 0x6c, 0x3e, 0x53, 0x31, 0xbb,
+ 0x31, 0xc9, 0xc0, 0xa9, 0xfe, 0x77, 0x45, 0x28, 0x27, 0x8c, 0xa2, 0x9f, 0x43, 0x25, 0xb9, 0x10,
+ 0x5b, 0xd3, 0x16, 0x26, 0x58, 0xea, 0xf7, 0xd4, 0x99, 0xce, 0x59, 0x84, 0xcb, 0xea, 0x6a, 0x4c,
+ 0xff, 0x8f, 0x02, 0xd4, 0x32, 0x0b, 0xa2, 0x82, 0xc3, 0xa6, 0x6d, 0xe2, 0x53, 0xd9, 0xcf, 0xde,
+ 0x01, 0x0d, 0x9b, 0x2f, 0xc6, 0xa6, 0x3d, 0x22, 0x46, 0xbb, 0x6d, 0x0e, 0x45, 0xc5, 0x97, 0x43,
+ 0x0f, 0x61, 0x37, 0x85, 0x62, 0xf3, 0x2b, 0xb3, 0x2d, 0xfa, 0xc5, 0xfe, 0x80, 0x60, 0xd3, 0xb0,
+ 0x65, 0x17, 0xfb, 0x00, 0x76, 0xd2, 0x12, 0xb2, 0x3d, 0xe8, 0x8f, 0xcc, 0x97, 0x23, 0xd2, 0x1f,
+ 0x8c, 0x48, 0x77, 0x30, 0xee, 0x77, 0xb4, 0x02, 0x6a, 0xc1, 0x9d, 0x13, 0xa3, 0xdf, 0x31, 0x46,
+ 0x03, 0xfc, 0x0d, 0xb1, 0x4c, 0x72, 0x62, 0xd9, 0xb6, 0xa8, 0x2b, 0x8b, 0x68, 0x17, 0xb6, 0xdb,
+ 0x83, 0x7e, 0xc7, 0x12, 0x45, 0xa9, 0xd1, 0xcb, 0xae, 0x6d, 0x8a, 0x32, 0xd7, 0xea, 0xab, 0x46,
+ 0xa8, 0x67, 0xf6, 0x8f, 0x47, 0xcf, 0xb5, 0x92, 0xc0, 0x5f, 0xa2, 0x64, 0xf5, 0xdb, 0x03, 0x8c,
+ 0xcd, 0xf6, 0x48, 0x2b, 0x0b, 0x26, 0x52, 0xfc, 0xee, 0x00, 0x7f, 0x6d, 0xe0, 0x8e, 0xd5, 0x3f,
+ 0x26, 0xc3, 0x41, 0xcf, 0x6a, 0x7f, 0xa3, 0x55, 0xd0, 0xc7, 0xb0, 0xb7, 0x58, 0x26, 0x23, 0xd3,
+ 0xea, 0x10, 0xa3, 0xd7, 0x1b, 0xa8, 0x46, 0x9c, 0x0c, 0x86, 0xb2, 0x1f, 0xaf, 0xa2, 0x8f, 0xe0,
+ 0xc3, 0xfe, 0x80, 0x98, 0xf6, 0xc8, 0x78, 0xd6, 0xb3, 0xec, 0xe7, 0x66, 0x87, 0x0c, 0xbb, 0xed,
+ 0x21, 0x31, 0x6c, 0x7b, 0xd0, 0xb6, 0x54, 0xd3, 0x0e, 0xe8, 0x31, 0x7c, 0x82, 0xc7, 0x3d, 0x53,
+ 0x3d, 0x03, 0xc8, 0xed, 0x98, 0x9c, 0x0c, 0x3a, 0x8b, 0xbe, 0x9e, 0xa4, 0x1d, 0x76, 0x0d, 0x7d,
+ 0x00, 0x2d, 0x49, 0xc0, 0xec, 0x8f, 0x04, 0xc7, 0x52, 0x3e, 0xc7, 0xa6, 0x2d, 0x09, 0xd5, 0xc5,
+ 0x75, 0xa4, 0x18, 0xed, 0xc1, 0x18, 0xb7, 0x4d, 0x9b, 0x18, 0xa7, 0x86, 0xd5, 0x33, 0x9e, 0xf5,
+ 0x4c, 0xad, 0x81, 0x76, 0xe0, 0xae, 0xd0, 0x8a, 0xd5, 0x36, 0xa5, 0x2c, 0xed, 0xf1, 0x70, 0x38,
+ 0xc0, 0x42, 0x1d, 0x4d, 0xd9, 0x00, 0x7c, 0x63, 0x8f, 0xcc, 0x93, 0xc5, 0x41, 0x5b, 0xfa, 0x33,
+ 0xd8, 0x5e, 0x6f, 0x46, 0x68, 0x5f, 0xa4, 0x0c, 0x9e, 0xb4, 0x49, 0x59, 0x37, 0x1a, 0x4c, 0x26,
+ 0xcc, 0xa7, 0x9e, 0x7f, 0x6e, 0x99, 0x22, 0x75, 0x70, 0xfd, 0xbf, 0x73, 0x50, 0xcb, 0x00, 0x45,
+ 0xfa, 0xf2, 0x28, 0xf3, 0x63, 0x6f, 0xe2, 0x31, 0x9e, 0xc4, 0xc6, 0x0c, 0xe4, 0xfa, 0xb7, 0x57,
+ 0xf4, 0x35, 0xb4, 0x5e, 0x05, 0x11, 0x61, 0x82, 0x0d, 0x37, 0x31, 0xfd, 0xf4, 0x61, 0xac, 0x70,
+ 0xa5, 0x60, 0x59, 0xf3, 0xa0, 0x86, 0xef, 0xbe, 0x0a, 0x22, 0x53, 0x6d, 0x97, 0x2f, 0xed, 0x6a,
+ 0x33, 0x7a, 0x0e, 0x5b, 0x94, 0x4d, 0xc9, 0x2b, 0xc6, 0x17, 0xf4, 0x54, 0xe8, 0xd9, 0xbb, 0xe9,
+ 0x3d, 0x0c, 0x37, 0x28, 0x9b, 0xbe, 0x60, 0x3c, 0xa1, 0xf4, 0xd9, 0x17, 0x50, 0x52, 0xc1, 0x5a,
+ 0x94, 0x9c, 0x1d, 0x3c, 0x18, 0xaa, 0xe2, 0x53, 0x98, 0x8e, 0x96, 0x13, 0xa3, 0x67, 0xe3, 0x6e,
+ 0x57, 0xcb, 0x8b, 0x51, 0x7f, 0xd0, 0x1e, 0x6a, 0x05, 0x89, 0x37, 0x1e, 0xf6, 0xb4, 0xe2, 0x67,
+ 0x3f, 0x81, 0x4a, 0x9a, 0x9b, 0x45, 0xcf, 0x63, 0xf5, 0xed, 0x91, 0xd1, 0xeb, 0x69, 0x1b, 0xa2,
+ 0x3c, 0xc5, 0xe6, 0xc9, 0xe0, 0xd4, 0x54, 0x24, 0xac, 0x4e, 0xcf, 0xd4, 0xf2, 0x87, 0xff, 0x5b,
+ 0x85, 0xea, 0x30, 0xfd, 0xa6, 0x89, 0x5e, 0xc2, 0xbd, 0xec, 0xf7, 0x38, 0x11, 0xa8, 0x78, 0x30,
+ 0x9d, 0x8a, 0x72, 0xe4, 0xe1, 0xea, 0xd7, 0xa0, 0xe5, 0x6f, 0x76, 0xbb, 0xf7, 0xdf, 0xf2, 0xb5,
+ 0x48, 0xdf, 0x40, 0x3d, 0x68, 0xda, 0x2c, 0xb6, 0x4f, 0xd2, 0x98, 0x14, 0xa1, 0xa5, 0x12, 0x68,
+ 0x91, 0x28, 0x76, 0x1f, 0xad, 0x0d, 0x61, 0xd9, 0x90, 0xa9, 0x6f, 0xa0, 0x61, 0xf2, 0xf9, 0x4a,
+ 0xbd, 0xdd, 0xaa, 0xc7, 0xe3, 0x07, 0xab, 0x0c, 0x2c, 0x7d, 0xc3, 0xbb, 0x89, 0x3f, 0x0c, 0x8d,
+ 0x25, 0x55, 0xa3, 0x9b, 0x52, 0xf7, 0xee, 0x0d, 0x56, 0xa2, 0x6f, 0xa0, 0x97, 0xb0, 0xb5, 0xa2,
+ 0x6e, 0x74, 0x73, 0x85, 0xb1, 0x7b, 0xa3, 0xb5, 0xe8, 0x1b, 0xc8, 0x80, 0xe6, 0x31, 0x8b, 0xd5,
+ 0x05, 0xc7, 0x91, 0x73, 0xce, 0x50, 0x9a, 0xde, 0xe4, 0x37, 0xe8, 0x83, 0xd3, 0xc0, 0xa3, 0xbb,
+ 0xbb, 0x2b, 0xef, 0xbb, 0x98, 0xb9, 0x01, 0xa7, 0xf2, 0x51, 0x40, 0xdf, 0x40, 0xbf, 0x00, 0x90,
+ 0x15, 0xb8, 0xa4, 0x8c, 0xb6, 0xd7, 0xbf, 0x39, 0xee, 0xde, 0xbb, 0xe6, 0x45, 0x4f, 0x11, 0xc0,
+ 0xf2, 0x19, 0xff, 0x37, 0x25, 0xd0, 0x81, 0x2d, 0xf5, 0x9e, 0x93, 0x3e, 0x62, 0x46, 0xbf, 0x09,
+ 0x95, 0x3e, 0x6c, 0x5d, 0x7e, 0x48, 0x55, 0x42, 0xfe, 0x60, 0x55, 0xd5, 0xd9, 0x8f, 0xac, 0x37,
+ 0x19, 0x02, 0x83, 0xdd, 0xeb, 0xdf, 0xac, 0xd0, 0x0f, 0xfa, 0x14, 0xfb, 0x2e, 0x6c, 0x2f, 0x9e,
+ 0x33, 0xd7, 0xb0, 0x9d, 0xfd, 0xd0, 0x7d, 0x13, 0xdb, 0x5d, 0xa8, 0x1b, 0x94, 0x2e, 0xa8, 0xa1,
+ 0xb7, 0x7d, 0x05, 0x7f, 0x1b, 0x5f, 0x96, 0xb0, 0xd9, 0x29, 0x8b, 0xd9, 0x7b, 0x21, 0xa5, 0x44,
+ 0x64, 0x0d, 0xbb, 0xd6, 0xcb, 0x1f, 0x45, 0xea, 0x57, 0xb0, 0x7d, 0xcc, 0xe2, 0x75, 0xcf, 0x6e,
+ 0x6b, 0xec, 0x7e, 0xc9, 0x31, 0xaf, 0x6e, 0x79, 0x76, 0xff, 0x8f, 0x77, 0x24, 0xc2, 0x93, 0x69,
+ 0xcc, 0x9e, 0xb8, 0xd3, 0x60, 0x4e, 0x9f, 0x9c, 0x07, 0xc9, 0x1f, 0x2c, 0xce, 0x4a, 0xf2, 0xf7,
+ 0xa7, 0xff, 0x1f, 0x00, 0x00, 0xff, 0xff, 0x3e, 0xd5, 0x68, 0x75, 0xf4, 0x21, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
diff --git a/lte/cloud/go/protos/subscriberdb.pb.go b/lte/cloud/go/protos/subscriberdb.pb.go
index 722a4b44ce1d..86b9b93c0d79 100644
--- a/lte/cloud/go/protos/subscriberdb.pb.go
+++ b/lte/cloud/go/protos/subscriberdb.pb.go
@@ -1049,6 +1049,104 @@ func (m *SubscriberUpdate) GetMask() *field_mask.FieldMask {
return nil
}
+type ListSubscribersRequest struct {
+ // page_size is the maximum number of entities returned per request.
+ PageSize uint32 `protobuf:"varint,1,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"`
+ // page_token is a serialized entity page token for paginated loads.
+ PageToken string `protobuf:"bytes,2,opt,name=page_token,json=pageToken,proto3" json:"page_token,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *ListSubscribersRequest) Reset() { *m = ListSubscribersRequest{} }
+func (m *ListSubscribersRequest) String() string { return proto.CompactTextString(m) }
+func (*ListSubscribersRequest) ProtoMessage() {}
+func (*ListSubscribersRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor_d870e4203d378ec0, []int{10}
+}
+
+func (m *ListSubscribersRequest) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_ListSubscribersRequest.Unmarshal(m, b)
+}
+func (m *ListSubscribersRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_ListSubscribersRequest.Marshal(b, m, deterministic)
+}
+func (m *ListSubscribersRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_ListSubscribersRequest.Merge(m, src)
+}
+func (m *ListSubscribersRequest) XXX_Size() int {
+ return xxx_messageInfo_ListSubscribersRequest.Size(m)
+}
+func (m *ListSubscribersRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_ListSubscribersRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ListSubscribersRequest proto.InternalMessageInfo
+
+func (m *ListSubscribersRequest) GetPageSize() uint32 {
+ if m != nil {
+ return m.PageSize
+ }
+ return 0
+}
+
+func (m *ListSubscribersRequest) GetPageToken() string {
+ if m != nil {
+ return m.PageToken
+ }
+ return ""
+}
+
+type ListSubscribersResponse struct {
+ Subscribers []*SubscriberData `protobuf:"bytes,1,rep,name=subscribers,proto3" json:"subscribers,omitempty"`
+ // next_page_token is a serialized entity page token for subsequent paginated
+ // loads.
+ NextPageToken string `protobuf:"bytes,2,opt,name=next_page_token,json=nextPageToken,proto3" json:"next_page_token,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *ListSubscribersResponse) Reset() { *m = ListSubscribersResponse{} }
+func (m *ListSubscribersResponse) String() string { return proto.CompactTextString(m) }
+func (*ListSubscribersResponse) ProtoMessage() {}
+func (*ListSubscribersResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_d870e4203d378ec0, []int{11}
+}
+
+func (m *ListSubscribersResponse) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_ListSubscribersResponse.Unmarshal(m, b)
+}
+func (m *ListSubscribersResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_ListSubscribersResponse.Marshal(b, m, deterministic)
+}
+func (m *ListSubscribersResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_ListSubscribersResponse.Merge(m, src)
+}
+func (m *ListSubscribersResponse) XXX_Size() int {
+ return xxx_messageInfo_ListSubscribersResponse.Size(m)
+}
+func (m *ListSubscribersResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_ListSubscribersResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ListSubscribersResponse proto.InternalMessageInfo
+
+func (m *ListSubscribersResponse) GetSubscribers() []*SubscriberData {
+ if m != nil {
+ return m.Subscribers
+ }
+ return nil
+}
+
+func (m *ListSubscribersResponse) GetNextPageToken() string {
+ if m != nil {
+ return m.NextPageToken
+ }
+ return ""
+}
+
func init() {
proto.RegisterEnum("magma.lte.AccessNetworkIdentifier", AccessNetworkIdentifier_name, AccessNetworkIdentifier_value)
proto.RegisterEnum("magma.lte.SubscriberID_IDType", SubscriberID_IDType_name, SubscriberID_IDType_value)
@@ -1071,108 +1169,117 @@ func init() {
proto.RegisterType((*Non3GPPUserProfile)(nil), "magma.lte.Non3GPPUserProfile")
proto.RegisterType((*SubscriberData)(nil), "magma.lte.SubscriberData")
proto.RegisterType((*SubscriberUpdate)(nil), "magma.lte.SubscriberUpdate")
+ proto.RegisterType((*ListSubscribersRequest)(nil), "magma.lte.ListSubscribersRequest")
+ proto.RegisterType((*ListSubscribersResponse)(nil), "magma.lte.ListSubscribersResponse")
}
func init() { proto.RegisterFile("lte/protos/subscriberdb.proto", fileDescriptor_d870e4203d378ec0) }
var fileDescriptor_d870e4203d378ec0 = []byte{
- // 1528 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x57, 0xdd, 0x52, 0xdb, 0x48,
- 0x16, 0xf6, 0x1f, 0x06, 0x1f, 0x83, 0x11, 0xbd, 0x24, 0x18, 0xb3, 0x6c, 0xbc, 0x4a, 0xed, 0x2e,
- 0xf9, 0x33, 0x29, 0xb3, 0xc9, 0x66, 0x37, 0x55, 0xbb, 0x2b, 0x63, 0x87, 0xa8, 0xc6, 0x16, 0x9e,
- 0x96, 0x21, 0x53, 0xb9, 0x51, 0xb5, 0xa5, 0xc6, 0x51, 0x21, 0x4b, 0x42, 0x2d, 0x13, 0xb8, 0x9c,
- 0xfb, 0x79, 0x92, 0x79, 0x81, 0xb9, 0x9b, 0x47, 0x98, 0x17, 0x98, 0xfb, 0x79, 0x8d, 0x99, 0xea,
- 0x96, 0x64, 0x84, 0xb1, 0xa9, 0xc9, 0x5c, 0x59, 0x7d, 0xbe, 0xef, 0x9c, 0xee, 0x73, 0xfa, 0xeb,
- 0xee, 0x63, 0xd8, 0x75, 0x42, 0xba, 0xef, 0x07, 0x5e, 0xe8, 0xb1, 0x7d, 0x36, 0x19, 0x32, 0x33,
- 0xb0, 0x87, 0x34, 0xb0, 0x86, 0x0d, 0x61, 0x43, 0xa5, 0x31, 0x19, 0x8d, 0x49, 0xc3, 0x09, 0x69,
- 0x6d, 0xdb, 0x0b, 0xcc, 0x37, 0x41, 0xc2, 0x35, 0xbd, 0xf1, 0xd8, 0x73, 0x23, 0x56, 0xad, 0x3e,
- 0xf2, 0xbc, 0x91, 0x13, 0xc7, 0x19, 0x4e, 0xce, 0xf6, 0xcf, 0x6c, 0xea, 0x58, 0xc6, 0x98, 0xb0,
- 0xf3, 0x88, 0x21, 0x9f, 0xc1, 0xaa, 0x3e, 0x8d, 0xae, 0xb6, 0x51, 0x05, 0x72, 0xb6, 0x55, 0xcd,
- 0xd6, 0xb3, 0x7b, 0x25, 0x9c, 0xb3, 0x2d, 0xd4, 0x84, 0x42, 0x78, 0xed, 0xd3, 0x6a, 0xae, 0x9e,
- 0xdd, 0xab, 0x34, 0xff, 0xd2, 0x98, 0x4e, 0xdb, 0x48, 0xbb, 0x35, 0xd4, 0xf6, 0xe0, 0xda, 0xa7,
- 0x58, 0x70, 0x65, 0x04, 0xc5, 0x68, 0x8c, 0x56, 0xa0, 0xa0, 0xf6, 0x74, 0x55, 0xca, 0xc8, 0xff,
- 0x85, 0xf5, 0xb4, 0x83, 0x4e, 0x43, 0xf4, 0x0c, 0x0a, 0xcc, 0xb6, 0x58, 0x35, 0x5b, 0xcf, 0xef,
- 0x95, 0x9b, 0x5b, 0x0b, 0x42, 0x63, 0x41, 0x92, 0x7f, 0xc8, 0xc1, 0xfa, 0x91, 0xde, 0x8b, 0x11,
- 0x3f, 0xb4, 0x3d, 0x17, 0x75, 0x60, 0x89, 0x85, 0x24, 0xa4, 0x62, 0xb9, 0x95, 0xe6, 0x7e, 0x2a,
- 0xc2, 0x0c, 0x75, 0x76, 0xac, 0x73, 0x37, 0x1c, 0x79, 0xa3, 0x43, 0x28, 0x91, 0x49, 0xf8, 0xc9,
- 0x20, 0xce, 0xc8, 0x8b, 0xf3, 0xfc, 0xfb, 0xfd, 0xa1, 0x94, 0x49, 0xf8, 0x49, 0x71, 0x46, 0x1e,
- 0x5e, 0x21, 0xf1, 0x17, 0xda, 0x06, 0xf1, 0x6d, 0x9c, 0xd3, 0xeb, 0x6a, 0xbe, 0x9e, 0xdd, 0x5b,
- 0xc5, 0xcb, 0x7c, 0xfc, 0x15, 0xbd, 0x46, 0x8f, 0xa0, 0x2c, 0xa0, 0x70, 0xe2, 0x3b, 0x94, 0x55,
- 0x0b, 0xf5, 0xfc, 0xde, 0x2a, 0x06, 0x6e, 0x1a, 0x08, 0x8b, 0xfc, 0x12, 0x36, 0xe7, 0xad, 0x0f,
- 0xad, 0xc2, 0x8a, 0xaa, 0x29, 0x87, 0x03, 0xf5, 0xb4, 0x23, 0x65, 0x10, 0x40, 0x31, 0xfe, 0xce,
- 0xca, 0x4f, 0xa1, 0x9c, 0x5a, 0x06, 0xda, 0x81, 0xad, 0x3e, 0xee, 0x1c, 0x1e, 0xf7, 0xfa, 0x27,
- 0x83, 0x4e, 0xdb, 0x50, 0x4e, 0x06, 0xef, 0x8d, 0xc1, 0x49, 0xbf, 0xdb, 0xd1, 0xa5, 0x8c, 0xfc,
- 0x6b, 0x0e, 0xd6, 0xbb, 0x83, 0xce, 0xef, 0xad, 0xdc, 0x0c, 0x75, 0x76, 0xfc, 0x25, 0x95, 0x9b,
- 0x13, 0xea, 0xcb, 0x2a, 0x97, 0x40, 0x9e, 0x6f, 0x56, 0x0b, 0x37, 0xd0, 0xb1, 0x6f, 0xa2, 0x06,
- 0xfc, 0x89, 0x30, 0x66, 0x8f, 0x5c, 0x6a, 0x19, 0x43, 0xc2, 0xa8, 0xe1, 0x92, 0x31, 0x65, 0x55,
- 0xa8, 0xe7, 0xf7, 0x4a, 0x78, 0x23, 0x81, 0x5a, 0x84, 0x51, 0x8d, 0x03, 0xe8, 0x19, 0x4c, 0x8d,
- 0x86, 0xef, 0x39, 0xb6, 0x69, 0x53, 0x56, 0x2d, 0x0b, 0xb6, 0x94, 0x00, 0xfd, 0xd8, 0xce, 0x37,
- 0x64, 0x5e, 0xda, 0xf7, 0x6c, 0xc8, 0x0e, 0x94, 0x53, 0xd9, 0x71, 0x62, 0x4f, 0xed, 0x76, 0x34,
- 0xe5, 0xa8, 0x23, 0x65, 0xe4, 0xef, 0xb3, 0x69, 0xf1, 0x47, 0xa1, 0x9e, 0xc0, 0x86, 0x13, 0x52,
- 0x43, 0xa4, 0xe7, 0xd2, 0xab, 0xd0, 0x60, 0xf4, 0x42, 0xec, 0x46, 0x01, 0x57, 0x9c, 0x90, 0xf2,
- 0x48, 0x1a, 0xbd, 0x0a, 0x75, 0x7a, 0x81, 0xf6, 0x61, 0x33, 0x1c, 0xf9, 0xbe, 0x41, 0x08, 0x31,
- 0x18, 0x0d, 0x2e, 0x69, 0x20, 0x92, 0x15, 0x05, 0x2f, 0xe1, 0x0d, 0x8e, 0x29, 0x84, 0xe8, 0x02,
- 0xe1, 0xc9, 0xa2, 0xb7, 0x50, 0x9b, 0x75, 0x08, 0xe8, 0xc8, 0x66, 0x21, 0x0d, 0xa8, 0x25, 0x6a,
- 0xbc, 0x82, 0xb7, 0x6e, 0xb9, 0xe1, 0x29, 0x2c, 0x7f, 0x57, 0x04, 0x49, 0xe9, 0x6b, 0x87, 0x9e,
- 0x7b, 0x66, 0x8f, 0x26, 0x01, 0x11, 0x7a, 0xd9, 0x05, 0x30, 0x3d, 0x37, 0xe4, 0xeb, 0x8c, 0x6f,
- 0x87, 0x35, 0x5c, 0x8a, 0x2d, 0xaa, 0xc5, 0x8b, 0xcb, 0xe7, 0xb1, 0x4d, 0x6a, 0x30, 0xea, 0x50,
- 0x93, 0xfb, 0xc4, 0xcb, 0x93, 0x62, 0x40, 0x4f, 0xec, 0xe8, 0x08, 0xca, 0x17, 0x1e, 0x33, 0xfc,
- 0xc0, 0x3b, 0xb3, 0x1d, 0x2a, 0x96, 0x53, 0xbe, 0x25, 0x9b, 0xd9, 0xd9, 0x1b, 0x5f, 0x7b, 0x7a,
- 0x3f, 0x62, 0x63, 0xb8, 0xf0, 0x58, 0xfc, 0x8d, 0xfe, 0x05, 0x05, 0x32, 0x1e, 0x06, 0x42, 0x19,
- 0xe5, 0xe6, 0xe3, 0x74, 0x84, 0xd1, 0x28, 0xa0, 0x23, 0x12, 0x52, 0xab, 0x47, 0xae, 0xec, 0xf1,
- 0x64, 0xdc, 0xb2, 0xc3, 0x80, 0xeb, 0x56, 0x38, 0xa0, 0x57, 0x90, 0xf7, 0x2d, 0xb7, 0xba, 0x24,
- 0x04, 0xfb, 0xf8, 0xbe, 0x99, 0xfb, 0x6d, 0x4d, 0xdc, 0x6b, 0x9c, 0x8f, 0x9e, 0x03, 0x9a, 0x4a,
- 0x88, 0xeb, 0xdf, 0x36, 0x0d, 0xdb, 0xaf, 0x16, 0xa3, 0x34, 0x13, 0x44, 0x17, 0x80, 0xea, 0xa3,
- 0x43, 0x58, 0x09, 0x28, 0xf3, 0x26, 0x81, 0x49, 0xab, 0xcb, 0x62, 0x85, 0xff, 0xb8, 0x6f, 0x26,
- 0xa5, 0xaf, 0xe1, 0x98, 0x8e, 0xa7, 0x8e, 0xb5, 0x1f, 0xb3, 0x00, 0x37, 0xd9, 0xf3, 0xf3, 0x60,
- 0x3a, 0x84, 0xb1, 0x64, 0x13, 0x96, 0xf0, 0xb2, 0x18, 0xab, 0x16, 0xfa, 0x1b, 0x54, 0xfc, 0xc0,
- 0xf6, 0x02, 0x3b, 0xbc, 0x36, 0x1c, 0x7a, 0x49, 0x1d, 0x51, 0xff, 0x35, 0xbc, 0x96, 0x58, 0xbb,
- 0xdc, 0x88, 0x0e, 0xe0, 0x81, 0x1f, 0x50, 0x3a, 0x16, 0xa2, 0x36, 0x4c, 0xe2, 0x93, 0xa1, 0xed,
- 0xd8, 0xe1, 0x75, 0xac, 0x8a, 0xcd, 0x1b, 0xf0, 0x70, 0x8a, 0xa1, 0x7f, 0x43, 0x35, 0xe5, 0x74,
- 0x39, 0x71, 0x5c, 0x1a, 0x24, 0x7e, 0x85, 0x48, 0x4d, 0x37, 0xf8, 0x69, 0x1a, 0xae, 0x7d, 0x9b,
- 0x85, 0x72, 0x2a, 0x35, 0x71, 0xa2, 0x7d, 0x37, 0xd2, 0x6f, 0xf4, 0xc8, 0x2c, 0x13, 0xdf, 0x15,
- 0xaa, 0xdd, 0x05, 0xe0, 0x5b, 0xf6, 0x99, 0x5c, 0xf3, 0xb2, 0x46, 0xea, 0x29, 0xc5, 0x16, 0xd5,
- 0xe7, 0xb7, 0x68, 0x02, 0x8f, 0x89, 0x29, 0xd6, 0x5b, 0xc2, 0x89, 0x47, 0x8f, 0x98, 0x68, 0x0b,
- 0x96, 0x2f, 0x1d, 0xe2, 0xf2, 0xda, 0x14, 0x44, 0xea, 0x45, 0x3e, 0x54, 0x2d, 0xf9, 0x2d, 0x2c,
- 0xc7, 0xfb, 0x28, 0xde, 0xa3, 0xfe, 0xe9, 0x3f, 0xa5, 0x4c, 0xfc, 0xf5, 0x5a, 0xca, 0xf2, 0x63,
- 0xcc, 0x6d, 0xa7, 0xaf, 0xa5, 0x1c, 0x92, 0x60, 0x95, 0x7f, 0x1b, 0xc7, 0xd8, 0x10, 0x68, 0x5e,
- 0x76, 0xa1, 0xba, 0x48, 0x4d, 0x68, 0x0f, 0xa4, 0x31, 0xb9, 0x32, 0x86, 0xc4, 0xb5, 0x3e, 0xdb,
- 0x56, 0xf8, 0xc9, 0x98, 0x38, 0xf1, 0xd9, 0xa8, 0x8c, 0xc9, 0x55, 0x2b, 0x31, 0x9f, 0x38, 0x77,
- 0x99, 0x56, 0xb2, 0x3f, 0xb7, 0x98, 0x6d, 0x47, 0xfe, 0xa9, 0x00, 0x48, 0xf3, 0xdc, 0x83, 0xa3,
- 0x7e, 0xff, 0x84, 0xd1, 0x20, 0xd9, 0xf9, 0x87, 0x50, 0x1c, 0x33, 0x9b, 0x59, 0x6e, 0x5c, 0xb5,
- 0x78, 0x84, 0x3e, 0x02, 0x72, 0x3d, 0xd7, 0x38, 0xe0, 0xc7, 0xdd, 0xf6, 0x0d, 0x62, 0x9a, 0x94,
- 0xb1, 0xf8, 0x2a, 0x7e, 0x91, 0xd2, 0xdb, 0xdd, 0x90, 0x89, 0x49, 0xed, 0x2b, 0xc2, 0x09, 0xaf,
- 0xbb, 0x9e, 0xcb, 0xe3, 0xa8, 0x7e, 0x64, 0x40, 0x16, 0x3c, 0xbc, 0x1b, 0xdb, 0x20, 0xbe, 0x2b,
- 0x8a, 0x5f, 0x69, 0xbe, 0xfc, 0xa2, 0xf8, 0x5c, 0x05, 0x68, 0x66, 0x0a, 0xc5, 0x77, 0xff, 0xf8,
- 0x29, 0xfe, 0x0f, 0x00, 0x97, 0x92, 0x29, 0x8e, 0x51, 0x75, 0x49, 0x34, 0x11, 0x3b, 0xf7, 0x1c,
- 0x31, 0x5c, 0x22, 0xbe, 0x1b, 0x59, 0xd0, 0x3b, 0x58, 0x8b, 0xd3, 0x71, 0xa9, 0xb8, 0xd2, 0x8a,
- 0x22, 0x23, 0x39, 0xed, 0x2e, 0x70, 0x8d, 0x86, 0x9f, 0xbd, 0xe0, 0x5c, 0xb5, 0xa8, 0x1b, 0xda,
- 0x67, 0x36, 0x0d, 0x70, 0x99, 0x24, 0x80, 0x6a, 0xc9, 0xa7, 0xb0, 0x3e, 0x93, 0x26, 0xfa, 0x2b,
- 0xec, 0x6a, 0xc7, 0x9a, 0xc1, 0x6d, 0x86, 0x7e, 0xd2, 0xd2, 0x0f, 0xb1, 0xda, 0x1f, 0xa8, 0xc7,
- 0x9a, 0xa1, 0x74, 0xbb, 0xc7, 0x1f, 0x3a, 0x6d, 0x29, 0x83, 0xea, 0xf0, 0xe7, 0xf9, 0x94, 0x96,
- 0x82, 0x71, 0xa7, 0x2d, 0x65, 0x65, 0x75, 0x2a, 0x82, 0x54, 0xf9, 0x50, 0x15, 0x36, 0xa7, 0x7e,
- 0x4a, 0x5f, 0xd3, 0x8d, 0x8e, 0xa6, 0xb4, 0xba, 0xfc, 0x29, 0xda, 0x86, 0x07, 0xb7, 0x91, 0xb6,
- 0xaa, 0x0b, 0x28, 0x2b, 0xff, 0x9c, 0x83, 0xca, 0xcd, 0xe3, 0xd3, 0x26, 0x21, 0x41, 0x4f, 0x20,
- 0xcf, 0xe2, 0x1b, 0xe4, 0x9e, 0xbe, 0x8b, 0x73, 0xd0, 0x73, 0xc8, 0x8f, 0xd8, 0x58, 0x08, 0xaa,
- 0xdc, 0xac, 0x2d, 0xee, 0x8a, 0x30, 0xa7, 0x71, 0xb6, 0x13, 0x26, 0x57, 0x7a, 0x6d, 0x71, 0x27,
- 0x80, 0x39, 0x0d, 0xbd, 0x02, 0x70, 0xa3, 0xf2, 0x26, 0x67, 0xb6, 0xdc, 0x7c, 0x18, 0x3b, 0x89,
- 0x96, 0xb6, 0x91, 0x54, 0xbf, 0x8d, 0x4b, 0x6e, 0xb2, 0x11, 0xe8, 0x65, 0xd2, 0xbb, 0x2c, 0xdd,
- 0x99, 0x66, 0xe6, 0x91, 0x4d, 0xda, 0x94, 0x47, 0x50, 0x66, 0x93, 0xe1, 0xf4, 0xc5, 0x89, 0x6e,
- 0x6c, 0x60, 0x93, 0x61, 0x72, 0xba, 0xde, 0xc0, 0x4a, 0xa2, 0xf4, 0xf8, 0xae, 0xde, 0xbd, 0x57,
- 0xdb, 0x78, 0x39, 0x16, 0xb2, 0x7c, 0x01, 0xd2, 0xcd, 0xa4, 0x27, 0xbe, 0xc5, 0xa7, 0x7b, 0x01,
- 0x05, 0x8b, 0x84, 0x24, 0xae, 0xef, 0xf6, 0xdc, 0xf5, 0xf1, 0x7d, 0xc0, 0x82, 0x86, 0x1a, 0x50,
- 0xe0, 0xfd, 0xf8, 0xb4, 0xc6, 0x51, 0xcb, 0xde, 0x48, 0x5a, 0xf6, 0xc6, 0x3b, 0xde, 0xb2, 0xf7,
- 0x08, 0x3b, 0xc7, 0x82, 0xf7, 0xf4, 0x1d, 0x6c, 0x2d, 0xd0, 0x26, 0xbf, 0xd4, 0xde, 0xe3, 0x3e,
- 0x97, 0x58, 0x09, 0x96, 0x3e, 0xa8, 0x3d, 0xe5, 0x1b, 0x29, 0xcb, 0x8d, 0x1f, 0xba, 0x8a, 0x26,
- 0xe5, 0x78, 0x57, 0xd2, 0x19, 0xbc, 0xef, 0x60, 0xad, 0x33, 0x90, 0xf2, 0xcd, 0x5f, 0x72, 0xe9,
- 0xd6, 0xbf, 0xdd, 0x42, 0xff, 0x83, 0x35, 0xc5, 0xb2, 0x6e, 0x4c, 0x68, 0xf1, 0xd2, 0x6b, 0x1b,
- 0xb7, 0xf6, 0xe9, 0xd4, 0xb3, 0x2d, 0x39, 0x83, 0xfe, 0x0f, 0x52, 0x9b, 0x3a, 0x34, 0xa4, 0xa9,
- 0x18, 0x8b, 0xe4, 0x35, 0x3f, 0x42, 0x1b, 0xa4, 0xa8, 0x88, 0xa9, 0x08, 0x3b, 0x73, 0x23, 0x44,
- 0xb4, 0xf9, 0x51, 0x54, 0xd8, 0x38, 0xa2, 0xe1, 0x8c, 0xe8, 0x17, 0x2e, 0x64, 0x71, 0x96, 0x72,
- 0x06, 0xb5, 0x60, 0xbd, 0x6b, 0xb3, 0x54, 0x2c, 0x86, 0xee, 0x4e, 0x59, 0xab, 0x2d, 0x88, 0xad,
- 0xd3, 0x50, 0xce, 0xb4, 0x76, 0x3e, 0x6e, 0x0b, 0x78, 0x9f, 0xff, 0xa3, 0x33, 0x1d, 0x6f, 0x62,
- 0xed, 0x8f, 0xbc, 0xf8, 0xef, 0xda, 0xb0, 0x28, 0x7e, 0x0f, 0x7e, 0x0b, 0x00, 0x00, 0xff, 0xff,
- 0xa2, 0x5e, 0x28, 0x70, 0xef, 0x0d, 0x00, 0x00,
+ // 1634 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x57, 0xdb, 0x72, 0xe3, 0xb8,
+ 0x11, 0xd5, 0xcd, 0x17, 0xb5, 0x7c, 0xa1, 0x91, 0xd9, 0xb1, 0x2c, 0xc7, 0x59, 0x2f, 0xb7, 0xb2,
+ 0xf1, 0xde, 0xe4, 0x29, 0x4d, 0x76, 0xb3, 0xc9, 0x56, 0x25, 0xa1, 0x2c, 0x8d, 0x87, 0x15, 0x99,
+ 0x66, 0x40, 0xd9, 0x93, 0x9a, 0x17, 0x16, 0x44, 0xc2, 0x1a, 0x96, 0x29, 0x92, 0x26, 0x20, 0x8f,
+ 0x3d, 0x0f, 0xa9, 0xca, 0x7b, 0xbe, 0x24, 0x3f, 0x90, 0xb7, 0x7c, 0x42, 0x7e, 0x20, 0xef, 0xf9,
+ 0x8d, 0xa4, 0x00, 0x92, 0x12, 0xad, 0x5b, 0x65, 0xf2, 0x24, 0xa2, 0xfb, 0x74, 0x03, 0xdd, 0x38,
+ 0xdd, 0x68, 0xc1, 0x91, 0xcf, 0xe9, 0x69, 0x14, 0x87, 0x3c, 0x64, 0xa7, 0x6c, 0x3c, 0x60, 0x4e,
+ 0xec, 0x0d, 0x68, 0xec, 0x0e, 0x9a, 0x52, 0x86, 0xaa, 0x23, 0x32, 0x1c, 0x91, 0xa6, 0xcf, 0x69,
+ 0xe3, 0x20, 0x8c, 0x9d, 0x1f, 0xe2, 0x0c, 0xeb, 0x84, 0xa3, 0x51, 0x18, 0x24, 0xa8, 0xc6, 0xf1,
+ 0x30, 0x0c, 0x87, 0x7e, 0xea, 0x67, 0x30, 0xbe, 0x39, 0xbd, 0xf1, 0xa8, 0xef, 0xda, 0x23, 0xc2,
+ 0x6e, 0x13, 0x84, 0x7a, 0x03, 0x5b, 0xd6, 0xc4, 0xbb, 0xde, 0x41, 0x3b, 0x50, 0xf2, 0xdc, 0x7a,
+ 0xf1, 0xb8, 0x78, 0x52, 0xc5, 0x25, 0xcf, 0x45, 0x2d, 0xa8, 0xf0, 0xc7, 0x88, 0xd6, 0x4b, 0xc7,
+ 0xc5, 0x93, 0x9d, 0xd6, 0xcf, 0x9a, 0x93, 0x6d, 0x9b, 0x79, 0xb3, 0xa6, 0xde, 0xe9, 0x3f, 0x46,
+ 0x14, 0x4b, 0xac, 0x8a, 0x60, 0x3d, 0x59, 0xa3, 0x4d, 0xa8, 0xe8, 0x17, 0x96, 0xae, 0x14, 0xd4,
+ 0xdf, 0xc2, 0x6e, 0xde, 0xc0, 0xa2, 0x1c, 0x7d, 0x0d, 0x15, 0xe6, 0xb9, 0xac, 0x5e, 0x3c, 0x2e,
+ 0x9f, 0xd4, 0x5a, 0xfb, 0x4b, 0x5c, 0x63, 0x09, 0x52, 0xff, 0x5e, 0x82, 0xdd, 0x73, 0xeb, 0x22,
+ 0xd5, 0x44, 0xdc, 0x0b, 0x03, 0xd4, 0x85, 0x35, 0xc6, 0x09, 0xa7, 0xf2, 0xb8, 0x3b, 0xad, 0xd3,
+ 0x9c, 0x87, 0x19, 0xe8, 0xec, 0xda, 0x12, 0x66, 0x38, 0xb1, 0x46, 0x67, 0x50, 0x25, 0x63, 0xfe,
+ 0xce, 0x26, 0xfe, 0x30, 0x4c, 0xe3, 0xfc, 0x62, 0xb5, 0x2b, 0x6d, 0xcc, 0xdf, 0x69, 0xfe, 0x30,
+ 0xc4, 0x9b, 0x24, 0xfd, 0x42, 0x07, 0x20, 0xbf, 0xed, 0x5b, 0xfa, 0x58, 0x2f, 0x1f, 0x17, 0x4f,
+ 0xb6, 0xf0, 0x86, 0x58, 0xff, 0x81, 0x3e, 0xa2, 0x4f, 0xa1, 0x26, 0x55, 0x7c, 0x1c, 0xf9, 0x94,
+ 0xd5, 0x2b, 0xc7, 0xe5, 0x93, 0x2d, 0x0c, 0x42, 0xd4, 0x97, 0x12, 0xf5, 0x05, 0x3c, 0x5b, 0x74,
+ 0x3e, 0xb4, 0x05, 0x9b, 0xba, 0xa1, 0x9d, 0xf5, 0xf5, 0xeb, 0xae, 0x52, 0x40, 0x00, 0xeb, 0xe9,
+ 0x77, 0x51, 0xfd, 0x0a, 0x6a, 0xb9, 0x63, 0xa0, 0x43, 0xd8, 0x37, 0x71, 0xf7, 0xec, 0xf2, 0xc2,
+ 0xbc, 0xea, 0x77, 0x3b, 0xb6, 0x76, 0xd5, 0x7f, 0x6d, 0xf7, 0xaf, 0xcc, 0x5e, 0xd7, 0x52, 0x0a,
+ 0xea, 0x7f, 0x4a, 0xb0, 0xdb, 0xeb, 0x77, 0xff, 0xd7, 0xcc, 0xcd, 0x40, 0x67, 0xd7, 0x1f, 0x93,
+ 0xb9, 0x05, 0xae, 0x3e, 0x2e, 0x73, 0x99, 0x2a, 0x8c, 0x9c, 0x7a, 0x65, 0xaa, 0xba, 0x8c, 0x1c,
+ 0xd4, 0x84, 0x9f, 0x10, 0xc6, 0xbc, 0x61, 0x40, 0x5d, 0x7b, 0x40, 0x18, 0xb5, 0x03, 0x32, 0xa2,
+ 0xac, 0x0e, 0xc7, 0xe5, 0x93, 0x2a, 0xde, 0xcb, 0x54, 0x6d, 0xc2, 0xa8, 0x21, 0x14, 0xe8, 0x6b,
+ 0x98, 0x08, 0xed, 0x28, 0xf4, 0x3d, 0xc7, 0xa3, 0xac, 0x5e, 0x93, 0x68, 0x25, 0x53, 0x98, 0xa9,
+ 0x5c, 0x5c, 0xc8, 0xa2, 0xb0, 0x57, 0x5c, 0xc8, 0x21, 0xd4, 0x72, 0xd1, 0x09, 0xe0, 0x85, 0xde,
+ 0xeb, 0x1a, 0xda, 0x79, 0x57, 0x29, 0xa8, 0x7f, 0x2b, 0xe6, 0xc9, 0x9f, 0xb8, 0xfa, 0x12, 0xf6,
+ 0x7c, 0x4e, 0x6d, 0x19, 0x5e, 0x40, 0x1f, 0xb8, 0xcd, 0xe8, 0x9d, 0xbc, 0x8d, 0x0a, 0xde, 0xf1,
+ 0x39, 0x15, 0x9e, 0x0c, 0xfa, 0xc0, 0x2d, 0x7a, 0x87, 0x4e, 0xe1, 0x19, 0x1f, 0x46, 0x91, 0x4d,
+ 0x08, 0xb1, 0x19, 0x8d, 0xef, 0x69, 0x2c, 0x83, 0x95, 0x09, 0xaf, 0xe2, 0x3d, 0xa1, 0xd3, 0x08,
+ 0xb1, 0xa4, 0x46, 0x04, 0x8b, 0x7e, 0x84, 0xc6, 0xac, 0x41, 0x4c, 0x87, 0x1e, 0xe3, 0x34, 0xa6,
+ 0xae, 0xcc, 0xf1, 0x26, 0xde, 0x7f, 0x62, 0x86, 0x27, 0x6a, 0xf5, 0xaf, 0xeb, 0xa0, 0x68, 0xa6,
+ 0x71, 0x16, 0x06, 0x37, 0xde, 0x70, 0x1c, 0x13, 0xc9, 0x97, 0x23, 0x00, 0x27, 0x0c, 0xb8, 0x38,
+ 0x67, 0xda, 0x1d, 0xb6, 0x71, 0x35, 0x95, 0xe8, 0xae, 0x48, 0xae, 0xd8, 0xc7, 0x73, 0xa8, 0xcd,
+ 0xa8, 0x4f, 0x1d, 0x61, 0x93, 0x1e, 0x4f, 0x49, 0x15, 0x56, 0x26, 0x47, 0xe7, 0x50, 0xbb, 0x0b,
+ 0x99, 0x1d, 0xc5, 0xe1, 0x8d, 0xe7, 0x53, 0x79, 0x9c, 0xda, 0x13, 0xda, 0xcc, 0xee, 0xde, 0xfc,
+ 0x63, 0x68, 0x99, 0x09, 0x1a, 0xc3, 0x5d, 0xc8, 0xd2, 0x6f, 0xf4, 0x2b, 0xa8, 0x90, 0xd1, 0x20,
+ 0x96, 0xcc, 0xa8, 0xb5, 0x3e, 0xcf, 0x7b, 0x18, 0x0e, 0x63, 0x3a, 0x24, 0x9c, 0xba, 0x17, 0xe4,
+ 0xc1, 0x1b, 0x8d, 0x47, 0x6d, 0x8f, 0xc7, 0x82, 0xb7, 0xd2, 0x00, 0x7d, 0x07, 0xe5, 0xc8, 0x0d,
+ 0xea, 0x6b, 0x92, 0xb0, 0x9f, 0xaf, 0xda, 0xd9, 0xec, 0x18, 0xb2, 0xaf, 0x09, 0x3c, 0xfa, 0x06,
+ 0xd0, 0x84, 0x42, 0x82, 0xff, 0x9e, 0x63, 0x7b, 0x51, 0x7d, 0x3d, 0x09, 0x33, 0xd3, 0x58, 0x52,
+ 0xa1, 0x47, 0xe8, 0x0c, 0x36, 0x63, 0xca, 0xc2, 0x71, 0xec, 0xd0, 0xfa, 0x86, 0x3c, 0xe1, 0x2f,
+ 0x56, 0xed, 0xa4, 0x99, 0x06, 0x4e, 0xe1, 0x78, 0x62, 0xd8, 0xf8, 0x47, 0x11, 0x60, 0x1a, 0xbd,
+ 0xa8, 0x07, 0xc7, 0x27, 0x8c, 0x65, 0x97, 0xb0, 0x86, 0x37, 0xe4, 0x5a, 0x77, 0xd1, 0xcf, 0x61,
+ 0x27, 0x8a, 0xbd, 0x30, 0xf6, 0xf8, 0xa3, 0xed, 0xd3, 0x7b, 0xea, 0xcb, 0xfc, 0x6f, 0xe3, 0xed,
+ 0x4c, 0xda, 0x13, 0x42, 0xf4, 0x12, 0x3e, 0x89, 0x62, 0x4a, 0x47, 0x92, 0xd4, 0xb6, 0x43, 0x22,
+ 0x32, 0xf0, 0x7c, 0x8f, 0x3f, 0xa6, 0xac, 0x78, 0x36, 0x55, 0x9e, 0x4d, 0x74, 0xe8, 0xd7, 0x50,
+ 0xcf, 0x19, 0xdd, 0x8f, 0xfd, 0x80, 0xc6, 0x99, 0x5d, 0x25, 0x61, 0xd3, 0x54, 0x7f, 0x9d, 0x57,
+ 0x37, 0xfe, 0x52, 0x84, 0x5a, 0x2e, 0x34, 0x59, 0xd1, 0x51, 0x90, 0xf0, 0x37, 0x79, 0x64, 0x36,
+ 0x48, 0x14, 0x48, 0xd6, 0x1e, 0x01, 0x88, 0x2b, 0x7b, 0x4f, 0x1e, 0x45, 0x5a, 0x13, 0xf6, 0x54,
+ 0x53, 0x89, 0x1e, 0x89, 0x2e, 0x9a, 0xa9, 0x47, 0xc4, 0x91, 0xe7, 0xad, 0xe2, 0xcc, 0xe2, 0x82,
+ 0x38, 0x68, 0x1f, 0x36, 0xee, 0x7d, 0x12, 0x88, 0xdc, 0x54, 0x64, 0xe8, 0xeb, 0x62, 0xa9, 0xbb,
+ 0xea, 0x8f, 0xb0, 0x91, 0xde, 0xa3, 0x7c, 0x8f, 0xcc, 0xeb, 0x5f, 0x2a, 0x85, 0xf4, 0xeb, 0x7b,
+ 0xa5, 0x28, 0xca, 0x58, 0xc8, 0xae, 0xbf, 0x57, 0x4a, 0x48, 0x81, 0x2d, 0xf1, 0x6d, 0x5f, 0x62,
+ 0x5b, 0x6a, 0xcb, 0x6a, 0x00, 0xf5, 0x65, 0x6c, 0x42, 0x27, 0xa0, 0x8c, 0xc8, 0x83, 0x3d, 0x20,
+ 0x81, 0xfb, 0xde, 0x73, 0xf9, 0x3b, 0x7b, 0xec, 0xa7, 0xb5, 0xb1, 0x33, 0x22, 0x0f, 0xed, 0x4c,
+ 0x7c, 0xe5, 0xcf, 0x23, 0xdd, 0xec, 0x7e, 0x9e, 0x20, 0x3b, 0xbe, 0xfa, 0xcf, 0x0a, 0x20, 0x23,
+ 0x0c, 0x5e, 0x9e, 0x9b, 0xe6, 0x15, 0xa3, 0x71, 0x76, 0xf3, 0xcf, 0x61, 0x7d, 0xc4, 0x3c, 0xe6,
+ 0x06, 0x69, 0xd6, 0xd2, 0x15, 0x7a, 0x0b, 0x28, 0x08, 0x03, 0xfb, 0xa5, 0x28, 0x77, 0x2f, 0xb2,
+ 0x89, 0xe3, 0x50, 0xc6, 0xd2, 0x56, 0xfc, 0x6d, 0x8e, 0x6f, 0xf3, 0x2e, 0x33, 0x91, 0x6e, 0x6a,
+ 0xd2, 0x08, 0xef, 0x06, 0x61, 0x20, 0xfc, 0xe8, 0x51, 0x22, 0x40, 0x2e, 0x3c, 0x9f, 0xf7, 0x6d,
+ 0x93, 0x28, 0x90, 0xc9, 0xdf, 0x69, 0xbd, 0xf8, 0x28, 0xff, 0x82, 0x05, 0x68, 0x66, 0x0b, 0x2d,
+ 0x0a, 0xfe, 0xff, 0x2a, 0xfe, 0x0d, 0x80, 0xa0, 0x92, 0x23, 0xcb, 0xa8, 0xbe, 0x26, 0x87, 0x88,
+ 0xc3, 0x15, 0x25, 0x86, 0xab, 0x24, 0x0a, 0x12, 0x09, 0x7a, 0x05, 0xdb, 0x69, 0x38, 0x01, 0x95,
+ 0x2d, 0x6d, 0x5d, 0x46, 0xa4, 0xe6, 0xcd, 0xa5, 0xde, 0xa0, 0xfc, 0x7d, 0x18, 0xdf, 0xea, 0x2e,
+ 0x0d, 0xb8, 0x77, 0xe3, 0xd1, 0x18, 0xd7, 0x48, 0xa6, 0xd0, 0x5d, 0xf5, 0x1a, 0x76, 0x67, 0xc2,
+ 0x44, 0x9f, 0xc1, 0x91, 0x71, 0x69, 0xd8, 0x42, 0x66, 0x5b, 0x57, 0x6d, 0xeb, 0x0c, 0xeb, 0x66,
+ 0x5f, 0xbf, 0x34, 0x6c, 0xad, 0xd7, 0xbb, 0x7c, 0xd3, 0xed, 0x28, 0x05, 0x74, 0x0c, 0x3f, 0x5d,
+ 0x0c, 0x69, 0x6b, 0x18, 0x77, 0x3b, 0x4a, 0x51, 0xd5, 0x27, 0x24, 0xc8, 0xa5, 0x0f, 0xd5, 0xe1,
+ 0xd9, 0xc4, 0x4e, 0x33, 0x0d, 0xcb, 0xee, 0x1a, 0x5a, 0xbb, 0x27, 0x9e, 0xa2, 0x03, 0xf8, 0xe4,
+ 0xa9, 0xa6, 0xa3, 0x5b, 0x52, 0x55, 0x54, 0xff, 0x55, 0x82, 0x9d, 0xe9, 0xe3, 0xd3, 0x21, 0x9c,
+ 0xa0, 0x2f, 0xa1, 0xcc, 0xd2, 0x0e, 0xb2, 0x62, 0xee, 0x12, 0x18, 0xf4, 0x0d, 0x94, 0x87, 0x6c,
+ 0x24, 0x09, 0x55, 0x6b, 0x35, 0x96, 0x4f, 0x45, 0x58, 0xc0, 0x04, 0xda, 0xe7, 0x59, 0x4b, 0x6f,
+ 0x2c, 0x9f, 0x04, 0xb0, 0x80, 0xa1, 0xef, 0x00, 0x82, 0x24, 0xbd, 0x59, 0xcd, 0xd6, 0x5a, 0xcf,
+ 0x53, 0x23, 0x39, 0xd2, 0x36, 0xb3, 0xec, 0x77, 0x70, 0x35, 0xc8, 0x2e, 0x02, 0xbd, 0xc8, 0x66,
+ 0x97, 0xb5, 0xb9, 0x6d, 0x66, 0x1e, 0xd9, 0x6c, 0x4c, 0xf9, 0x14, 0x6a, 0x6c, 0x3c, 0x98, 0xbc,
+ 0x38, 0x49, 0xc7, 0x06, 0x36, 0x1e, 0x64, 0xd5, 0xf5, 0x03, 0x6c, 0x66, 0x4c, 0x4f, 0x7b, 0xf5,
+ 0xd1, 0x4a, 0x6e, 0xe3, 0x8d, 0x94, 0xc8, 0xea, 0x1d, 0x28, 0xd3, 0x4d, 0xaf, 0x22, 0x57, 0x6c,
+ 0xf7, 0x2d, 0x54, 0x5c, 0xc2, 0x49, 0x9a, 0xdf, 0x83, 0x85, 0xe7, 0x13, 0xf7, 0x80, 0x25, 0x0c,
+ 0x35, 0xa1, 0x22, 0xe6, 0xf1, 0x49, 0x8e, 0x93, 0x91, 0xbd, 0x99, 0x8d, 0xec, 0xcd, 0x57, 0x62,
+ 0x64, 0xbf, 0x20, 0xec, 0x16, 0x4b, 0x9c, 0xda, 0x87, 0xe7, 0x3d, 0x8f, 0xf1, 0xa9, 0x2f, 0x86,
+ 0xe9, 0xdd, 0x98, 0x32, 0x8e, 0x0e, 0xa1, 0x1a, 0x91, 0x21, 0xb5, 0x99, 0xf7, 0x81, 0xa6, 0x8d,
+ 0x68, 0x53, 0x08, 0x2c, 0xef, 0x83, 0x6c, 0xaf, 0x52, 0xc9, 0xc3, 0x5b, 0x9a, 0x3d, 0xce, 0x12,
+ 0xde, 0x17, 0x02, 0xf5, 0xcf, 0xb0, 0x3f, 0xe7, 0x95, 0x45, 0x61, 0xc0, 0xc4, 0x38, 0x51, 0x9b,
+ 0xfe, 0x01, 0xc9, 0xc6, 0xf5, 0x15, 0x61, 0xe5, 0xd1, 0xe8, 0x0b, 0xd8, 0x95, 0xe3, 0xcd, 0xdc,
+ 0xde, 0xdb, 0x42, 0x6c, 0x66, 0xfb, 0x7f, 0xf5, 0x0a, 0xf6, 0x97, 0x54, 0x9c, 0x68, 0xd5, 0xaf,
+ 0xb1, 0x29, 0x0a, 0xa7, 0x0a, 0x6b, 0x6f, 0xf4, 0x0b, 0xed, 0x4f, 0x4a, 0x51, 0x08, 0xdf, 0xf4,
+ 0x34, 0x43, 0x29, 0x89, 0x59, 0xab, 0xdb, 0x7f, 0xdd, 0xc5, 0x46, 0xb7, 0xaf, 0x94, 0x5b, 0xff,
+ 0x2e, 0xe5, 0xff, 0xd0, 0x74, 0xda, 0xe8, 0x77, 0xb0, 0xad, 0xb9, 0xee, 0x54, 0x84, 0x96, 0x9f,
+ 0xbc, 0xb1, 0xf7, 0x84, 0x7d, 0xd7, 0xa1, 0xe7, 0xaa, 0x05, 0xf4, 0x7b, 0x50, 0x3a, 0xd4, 0xa7,
+ 0x9c, 0xe6, 0x7c, 0x2c, 0x2b, 0x9a, 0xc5, 0x1e, 0x3a, 0xa0, 0x24, 0xd4, 0xc8, 0x79, 0x38, 0x5c,
+ 0xe8, 0x21, 0x81, 0x2d, 0xf6, 0xa2, 0xc3, 0xde, 0x39, 0xe5, 0x33, 0xa5, 0xbc, 0xf4, 0x20, 0xcb,
+ 0xa3, 0x54, 0x0b, 0xa8, 0x0d, 0xbb, 0x33, 0x97, 0x8d, 0xe6, 0xb7, 0x6c, 0x34, 0x96, 0xf8, 0xb6,
+ 0x28, 0x57, 0x0b, 0xad, 0x10, 0xf6, 0xf2, 0x79, 0x3e, 0xf3, 0xc3, 0xb1, 0x8b, 0xde, 0xce, 0x3b,
+ 0xfe, 0x2c, 0xdf, 0x06, 0x16, 0xf2, 0xb6, 0xa1, 0xae, 0x82, 0x24, 0x24, 0x54, 0x0b, 0xed, 0xc3,
+ 0xb7, 0x07, 0x12, 0x76, 0x2a, 0xfe, 0x18, 0x3b, 0x62, 0xbb, 0xd3, 0x61, 0x98, 0xfe, 0xeb, 0x1d,
+ 0xac, 0xcb, 0xdf, 0x97, 0xff, 0x0d, 0x00, 0x00, 0xff, 0xff, 0x34, 0xa4, 0xdf, 0xe6, 0x36, 0x0f,
+ 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@@ -1426,3 +1533,77 @@ var _SubscriberDB_serviceDesc = grpc.ServiceDesc{
Streams: []grpc.StreamDesc{},
Metadata: "lte/protos/subscriberdb.proto",
}
+
+// SubscriberDBCloudClient is the client API for SubscriberDBCloud service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
+type SubscriberDBCloudClient interface {
+ // ListSubscribers lists pages of subscribers stored.
+ ListSubscribers(ctx context.Context, in *ListSubscribersRequest, opts ...grpc.CallOption) (*ListSubscribersResponse, error)
+}
+
+type subscriberDBCloudClient struct {
+ cc grpc.ClientConnInterface
+}
+
+func NewSubscriberDBCloudClient(cc grpc.ClientConnInterface) SubscriberDBCloudClient {
+ return &subscriberDBCloudClient{cc}
+}
+
+func (c *subscriberDBCloudClient) ListSubscribers(ctx context.Context, in *ListSubscribersRequest, opts ...grpc.CallOption) (*ListSubscribersResponse, error) {
+ out := new(ListSubscribersResponse)
+ err := c.cc.Invoke(ctx, "/magma.lte.SubscriberDBCloud/ListSubscribers", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+// SubscriberDBCloudServer is the server API for SubscriberDBCloud service.
+type SubscriberDBCloudServer interface {
+ // ListSubscribers lists pages of subscribers stored.
+ ListSubscribers(context.Context, *ListSubscribersRequest) (*ListSubscribersResponse, error)
+}
+
+// UnimplementedSubscriberDBCloudServer can be embedded to have forward compatible implementations.
+type UnimplementedSubscriberDBCloudServer struct {
+}
+
+func (*UnimplementedSubscriberDBCloudServer) ListSubscribers(ctx context.Context, req *ListSubscribersRequest) (*ListSubscribersResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method ListSubscribers not implemented")
+}
+
+func RegisterSubscriberDBCloudServer(s *grpc.Server, srv SubscriberDBCloudServer) {
+ s.RegisterService(&_SubscriberDBCloud_serviceDesc, srv)
+}
+
+func _SubscriberDBCloud_ListSubscribers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(ListSubscribersRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(SubscriberDBCloudServer).ListSubscribers(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/magma.lte.SubscriberDBCloud/ListSubscribers",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(SubscriberDBCloudServer).ListSubscribers(ctx, req.(*ListSubscribersRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+var _SubscriberDBCloud_serviceDesc = grpc.ServiceDesc{
+ ServiceName: "magma.lte.SubscriberDBCloud",
+ HandlerType: (*SubscriberDBCloudServer)(nil),
+ Methods: []grpc.MethodDesc{
+ {
+ MethodName: "ListSubscribers",
+ Handler: _SubscriberDBCloud_ListSubscribers_Handler,
+ },
+ },
+ Streams: []grpc.StreamDesc{},
+ Metadata: "lte/protos/subscriberdb.proto",
+}
diff --git a/lte/cloud/go/serdes/serdes.go b/lte/cloud/go/serdes/serdes.go
index f150a27d59d0..33e9c5a323bc 100644
--- a/lte/cloud/go/serdes/serdes.go
+++ b/lte/cloud/go/serdes/serdes.go
@@ -16,6 +16,7 @@ package serdes
import (
"magma/lte/cloud/go/lte"
lte_models "magma/lte/cloud/go/services/lte/obsidian/models"
+ nprobe_models "magma/lte/cloud/go/services/nprobe/obsidian/models"
policydb_models "magma/lte/cloud/go/services/policydb/obsidian/models"
subscriberdb_models "magma/lte/cloud/go/services/subscriberdb/obsidian/models"
"magma/orc8r/cloud/go/serde"
@@ -34,7 +35,8 @@ var (
Entity = serdes.Entity.
MustMerge(lte_models.EntitySerdes).
MustMerge(subscriberdb_models.EntitySerdes).
- MustMerge(policydb_models.EntitySerdes)
+ MustMerge(policydb_models.EntitySerdes).
+ MustMerge(nprobe_models.EntitySerdes)
// State contains the full set of state serdes used in the LTE module
State = serdes.State.MustMerge(serde.NewRegistry(
state.NewStateSerde(lte.EnodebStateType, <e_models.EnodebState{}),
diff --git a/lte/cloud/go/services/nprobe/doc.go b/lte/cloud/go/services/nprobe/doc.go
new file mode 100644
index 000000000000..dd4ce740a54e
--- /dev/null
+++ b/lte/cloud/go/services/nprobe/doc.go
@@ -0,0 +1,17 @@
+/*
+Copyright 2020 The Magma Authors.
+
+This source code is licensed under the BSD-style license found in the
+LICENSE file in the root directory of this source tree.
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Package nprobe provides the network probe service.
+package nprobe
+
+const ServiceName = "nprobe"
diff --git a/lte/cloud/go/services/nprobe/nprobe/main.go b/lte/cloud/go/services/nprobe/nprobe/main.go
new file mode 100644
index 000000000000..3918973cde7c
--- /dev/null
+++ b/lte/cloud/go/services/nprobe/nprobe/main.go
@@ -0,0 +1,46 @@
+/*
+Copyright 2020 The Magma Authors.
+
+This source code is licensed under the BSD-style license found in the
+LICENSE file in the root directory of this source tree.
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package main
+
+import (
+ "magma/lte/cloud/go/lte"
+ "magma/lte/cloud/go/services/nprobe"
+ "magma/lte/cloud/go/services/nprobe/obsidian/handlers"
+
+ "magma/orc8r/cloud/go/obsidian"
+ "magma/orc8r/cloud/go/obsidian/swagger"
+ "magma/orc8r/cloud/go/obsidian/swagger/protos"
+ "magma/orc8r/cloud/go/service"
+
+ "github.com/golang/glog"
+)
+
+func main() {
+ // Create service
+ srv, err := service.NewOrchestratorService(lte.ModuleName, nprobe.ServiceName)
+ if err != nil {
+ glog.Fatalf("Error creating service: %v", err)
+ }
+
+ // Attach handlers
+ obsidian.AttachHandlers(srv.EchoServer, handlers.GetHandlers())
+ protos.RegisterSwaggerSpecServer(srv.GrpcServer, swagger.NewSpecServicerFromFile(nprobe.ServiceName))
+
+ // Run service
+ err = srv.Run()
+ if err != nil {
+ glog.Fatalf("Error while running service and echo server: %v", err)
+ }
+
+}
diff --git a/lte/cloud/go/services/nprobe/obsidian/handlers/handlers.go b/lte/cloud/go/services/nprobe/obsidian/handlers/handlers.go
new file mode 100644
index 000000000000..01093ef5b745
--- /dev/null
+++ b/lte/cloud/go/services/nprobe/obsidian/handlers/handlers.go
@@ -0,0 +1,292 @@
+/*
+ * Copyright 2020 The Magma Authors.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package handlers
+
+import (
+ "math/rand"
+ "net/http"
+ "time"
+
+ "magma/lte/cloud/go/lte"
+ "magma/lte/cloud/go/serdes"
+ "magma/lte/cloud/go/services/lte/obsidian/handlers"
+ "magma/lte/cloud/go/services/nprobe/obsidian/models"
+
+ "magma/orc8r/cloud/go/obsidian"
+ "magma/orc8r/cloud/go/services/configurator"
+ merrors "magma/orc8r/lib/go/errors"
+
+ strfmt "github.com/go-openapi/strfmt"
+ "github.com/labstack/echo"
+ "github.com/pkg/errors"
+)
+
+const (
+ NetworkProbePath = handlers.ManageNetworkPath + obsidian.UrlSep + "network_probe"
+
+ NetworkProbeTasksPath = NetworkProbePath + obsidian.UrlSep + "tasks"
+ NetworkProbeDestinationsPath = NetworkProbePath + obsidian.UrlSep + "destinations"
+
+ NetworkProbeTaskDetailsPath = NetworkProbeTasksPath + obsidian.UrlSep + ":task_id"
+ NetworkProbeDestinationDetailsPath = NetworkProbeDestinationsPath + obsidian.UrlSep + ":destination_id"
+)
+
+func GetHandlers() []obsidian.Handler {
+ ret := []obsidian.Handler{
+ {Path: NetworkProbeTasksPath, Methods: obsidian.GET, HandlerFunc: listNetworkProbeTasks},
+ {Path: NetworkProbeTasksPath, Methods: obsidian.POST, HandlerFunc: createNetworkProbeTask},
+ {Path: NetworkProbeTaskDetailsPath, Methods: obsidian.GET, HandlerFunc: getNetworkProbeTask},
+ {Path: NetworkProbeTaskDetailsPath, Methods: obsidian.PUT, HandlerFunc: updateNetworkProbeTask},
+ {Path: NetworkProbeTaskDetailsPath, Methods: obsidian.DELETE, HandlerFunc: deleteNetworkProbeTask},
+
+ {Path: NetworkProbeDestinationsPath, Methods: obsidian.GET, HandlerFunc: listNetworkProbeDestinations},
+ {Path: NetworkProbeDestinationsPath, Methods: obsidian.POST, HandlerFunc: createNetworkProbeDestination},
+ {Path: NetworkProbeDestinationDetailsPath, Methods: obsidian.GET, HandlerFunc: getNetworkProbeDestination},
+ {Path: NetworkProbeDestinationDetailsPath, Methods: obsidian.PUT, HandlerFunc: updateNetworkProbeDestination},
+ {Path: NetworkProbeDestinationDetailsPath, Methods: obsidian.DELETE, HandlerFunc: deleteNetworkProbeDestination},
+ }
+ return ret
+}
+
+func listNetworkProbeTasks(c echo.Context) error {
+ networkID, nerr := obsidian.GetNetworkId(c)
+ if nerr != nil {
+ return nerr
+ }
+
+ ents, _, err := configurator.LoadAllEntitiesOfType(
+ networkID, lte.NetworkProbeTaskEntityType,
+ configurator.EntityLoadCriteria{LoadConfig: true},
+ serdes.Entity,
+ )
+ if err == merrors.ErrNotFound {
+ return echo.ErrNotFound
+ }
+ if err != nil {
+ return obsidian.HttpError(errors.Wrap(err, "failed to load existing NetworkProbeTasks"), http.StatusInternalServerError)
+ }
+
+ ret := make(map[string]*models.NetworkProbeTask, len(ents))
+ for _, ent := range ents {
+ ret[ent.Key] = (&models.NetworkProbeTask{}).FromBackendModels(ent)
+ }
+ return c.JSON(http.StatusOK, ret)
+}
+
+func createNetworkProbeTask(c echo.Context) error {
+ networkID, nerr := obsidian.GetNetworkId(c)
+ if nerr != nil {
+ return nerr
+ }
+
+ payload := &models.NetworkProbeTask{}
+ if err := c.Bind(payload); err != nil {
+ return obsidian.HttpError(err, http.StatusBadRequest)
+ }
+ if err := payload.ValidateModel(); err != nil {
+ return obsidian.HttpError(err, http.StatusBadRequest)
+ }
+
+ // generate random correlation ID if not provided
+ if payload.TaskDetails.CorrelationID == 0 {
+ payload.TaskDetails.CorrelationID = rand.Uint64()
+ }
+
+ payload.TaskDetails.Timestamp = strfmt.DateTime(time.Now().UTC())
+ _, err := configurator.CreateEntity(
+ networkID,
+ configurator.NetworkEntity{
+ Type: lte.NetworkProbeTaskEntityType,
+ Key: string(payload.TaskID),
+ Config: payload.TaskDetails,
+ },
+ serdes.Entity,
+ )
+ if err != nil {
+ return obsidian.HttpError(err, http.StatusInternalServerError)
+ }
+
+ return c.NoContent(http.StatusCreated)
+}
+
+func getNetworkProbeTask(c echo.Context) error {
+ paramNames := []string{"network_id", "task_id"}
+ values, nerr := obsidian.GetParamValues(c, paramNames...)
+ if nerr != nil {
+ return nerr
+ }
+
+ networkID, taskID := values[0], values[1]
+ ent, err := configurator.LoadEntity(networkID,
+ lte.NetworkProbeTaskEntityType,
+ taskID,
+ configurator.EntityLoadCriteria{LoadConfig: true},
+ serdes.Entity)
+ if err == merrors.ErrNotFound {
+ return echo.ErrNotFound
+ }
+ if err != nil {
+ return obsidian.HttpError(err, http.StatusInternalServerError)
+ }
+
+ ret := (&models.NetworkProbeTask{}).FromBackendModels(ent)
+ return c.JSON(http.StatusOK, ret)
+}
+
+func updateNetworkProbeTask(c echo.Context) error {
+ networkID, nerr := obsidian.GetNetworkId(c)
+ if nerr != nil {
+ return nerr
+ }
+
+ payload := &models.NetworkProbeTask{}
+ if err := c.Bind(payload); err != nil {
+ return obsidian.HttpError(err, http.StatusBadRequest)
+ }
+ if err := payload.ValidateModel(); err != nil {
+ return obsidian.HttpError(err, http.StatusBadRequest)
+ }
+
+ _, err := configurator.UpdateEntity(networkID, payload.ToEntityUpdateCriteria(), serdes.Entity)
+ if err != nil {
+ return obsidian.HttpError(err, http.StatusInternalServerError)
+ }
+ return c.NoContent(http.StatusNoContent)
+}
+
+func deleteNetworkProbeTask(c echo.Context) error {
+ paramNames := []string{"network_id", "task_id"}
+ values, nerr := obsidian.GetParamValues(c, paramNames...)
+ if nerr != nil {
+ return nerr
+ }
+
+ networkID, taskID := values[0], values[1]
+ err := configurator.DeleteEntity(networkID, lte.NetworkProbeTaskEntityType, taskID)
+ if err != nil {
+ return obsidian.HttpError(err, http.StatusInternalServerError)
+ }
+ return c.NoContent(http.StatusNoContent)
+}
+
+func listNetworkProbeDestinations(c echo.Context) error {
+ networkID, nerr := obsidian.GetNetworkId(c)
+ if nerr != nil {
+ return nerr
+ }
+
+ ents, _, err := configurator.LoadAllEntitiesOfType(
+ networkID, lte.NetworkProbeDestinationEntityType,
+ configurator.EntityLoadCriteria{LoadConfig: true},
+ serdes.Entity,
+ )
+ if err != nil {
+ return obsidian.HttpError(err, http.StatusInternalServerError)
+ }
+
+ ret := make(map[string]*models.NetworkProbeDestination, len(ents))
+ for _, ent := range ents {
+ ret[ent.Key] = (&models.NetworkProbeDestination{}).FromBackendModels(ent)
+ }
+ return c.JSON(http.StatusOK, ret)
+}
+
+func createNetworkProbeDestination(c echo.Context) error {
+ networkID, nerr := obsidian.GetNetworkId(c)
+ if nerr != nil {
+ return nerr
+ }
+
+ payload := &models.NetworkProbeDestination{}
+ if err := c.Bind(payload); err != nil {
+ return obsidian.HttpError(err, http.StatusBadRequest)
+ }
+ if err := payload.ValidateModel(); err != nil {
+ return obsidian.HttpError(err, http.StatusBadRequest)
+ }
+
+ _, err := configurator.CreateEntity(
+ networkID,
+ configurator.NetworkEntity{
+ Type: lte.NetworkProbeDestinationEntityType,
+ Key: string(payload.DestinationID),
+ Config: payload.DestinationDetails,
+ },
+ serdes.Entity,
+ )
+ if err != nil {
+ return obsidian.HttpError(err, http.StatusInternalServerError)
+ }
+ return c.NoContent(http.StatusCreated)
+}
+
+func getNetworkProbeDestination(c echo.Context) error {
+ paramNames := []string{"network_id", "destination_id"}
+ values, nerr := obsidian.GetParamValues(c, paramNames...)
+ if nerr != nil {
+ return nerr
+ }
+
+ networkID, destinationID := values[0], values[1]
+ ent, err := configurator.LoadEntity(networkID,
+ lte.NetworkProbeDestinationEntityType,
+ destinationID,
+ configurator.EntityLoadCriteria{LoadConfig: true},
+ serdes.Entity)
+ if err == merrors.ErrNotFound {
+ return echo.ErrNotFound
+ }
+ if err != nil {
+ return obsidian.HttpError(err, http.StatusInternalServerError)
+ }
+
+ ret := (&models.NetworkProbeDestination{}).FromBackendModels(ent)
+ return c.JSON(http.StatusOK, ret)
+}
+
+func updateNetworkProbeDestination(c echo.Context) error {
+ networkID, nerr := obsidian.GetNetworkId(c)
+ if nerr != nil {
+ return nerr
+ }
+
+ payload := &models.NetworkProbeDestination{}
+ if err := c.Bind(payload); err != nil {
+ return obsidian.HttpError(err, http.StatusBadRequest)
+ }
+ if err := payload.ValidateModel(); err != nil {
+ return obsidian.HttpError(err, http.StatusBadRequest)
+ }
+
+ _, err := configurator.UpdateEntity(networkID, payload.ToEntityUpdateCriteria(), serdes.Entity)
+ if err != nil {
+ return obsidian.HttpError(err, http.StatusInternalServerError)
+ }
+ return c.NoContent(http.StatusNoContent)
+}
+
+func deleteNetworkProbeDestination(c echo.Context) error {
+ paramNames := []string{"network_id", "destination_id"}
+ values, nerr := obsidian.GetParamValues(c, paramNames...)
+ if nerr != nil {
+ return nerr
+ }
+
+ networkID, destinationID := values[0], values[1]
+ err := configurator.DeleteEntity(networkID, lte.NetworkProbeDestinationEntityType, destinationID)
+ if err != nil {
+ return obsidian.HttpError(err, http.StatusInternalServerError)
+ }
+ return c.NoContent(http.StatusNoContent)
+}
diff --git a/lte/cloud/go/services/nprobe/obsidian/handlers/handlers_test.go b/lte/cloud/go/services/nprobe/obsidian/handlers/handlers_test.go
new file mode 100644
index 000000000000..af96ce504d2e
--- /dev/null
+++ b/lte/cloud/go/services/nprobe/obsidian/handlers/handlers_test.go
@@ -0,0 +1,662 @@
+/*
+ * Copyright 2020 The Magma Authors.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package handlers_test
+
+import (
+ "testing"
+ "time"
+
+ "magma/lte/cloud/go/lte"
+ "magma/lte/cloud/go/serdes"
+ "magma/lte/cloud/go/services/nprobe/obsidian/handlers"
+ "magma/lte/cloud/go/services/nprobe/obsidian/models"
+ "magma/orc8r/cloud/go/obsidian"
+ "magma/orc8r/cloud/go/obsidian/tests"
+ "magma/orc8r/cloud/go/services/configurator"
+ configuratorTestInit "magma/orc8r/cloud/go/services/configurator/test_init"
+
+ "github.com/go-openapi/strfmt"
+ "github.com/labstack/echo"
+ "github.com/stretchr/testify/assert"
+)
+
+func init() {
+ //_ = flag.Set("alsologtostderr", "true") // uncomment to view logs during test
+}
+
+func TestCreateNetworkProbeTask(t *testing.T) {
+ configuratorTestInit.StartTestService(t)
+ err := configurator.CreateNetwork(configurator.Network{ID: "n1"}, serdes.Network)
+ assert.NoError(t, err)
+
+ e := echo.New()
+ testURLRoot := "/magma/v1/lte/:network_id/network_probe/tasks"
+ handlers := handlers.GetHandlers()
+ createNetworkProbeTask := tests.GetHandlerByPathAndMethod(t, handlers, testURLRoot, obsidian.POST).HandlerFunc
+
+ payload := &models.NetworkProbeTask{
+ TaskID: "test",
+ TaskDetails: &models.NetworkProbeTaskDetails{
+ TargetID: "test",
+ TargetType: "imsi",
+ DeliveryType: "all",
+ CorrelationID: 8674665223082154000,
+ Timestamp: strfmt.DateTime(time.Now().UTC()),
+ },
+ }
+
+ tc := tests.Test{
+ Method: "POST",
+ URL: testURLRoot,
+ Payload: payload,
+ Handler: createNetworkProbeTask,
+ ParamNames: []string{"network_id"},
+ ParamValues: []string{"n1"},
+ ExpectedStatus: 201,
+ }
+ tests.RunUnitTest(t, e, tc)
+
+ actual, err := configurator.LoadEntity("n1", lte.NetworkProbeTaskEntityType, "test", configurator.FullEntityLoadCriteria(), serdes.Entity)
+ assert.NoError(t, err)
+ expected := configurator.NetworkEntity{
+ NetworkID: "n1",
+ Type: lte.NetworkProbeTaskEntityType,
+ Key: "test",
+ Config: payload.TaskDetails,
+ GraphID: "2",
+ }
+
+ expected_task := expected.Config.(*models.NetworkProbeTaskDetails)
+ actual_task := actual.Config.(*models.NetworkProbeTaskDetails)
+
+ assert.Equal(t, expected_task.TargetID, actual_task.TargetID)
+ assert.Equal(t, expected_task.TargetType, actual_task.TargetType)
+ assert.Equal(t, expected_task.DeliveryType, actual_task.DeliveryType)
+ assert.Equal(t, expected_task.CorrelationID, actual_task.CorrelationID)
+}
+
+func TestListNetworkProbeTasks(t *testing.T) {
+ configuratorTestInit.StartTestService(t)
+ err := configurator.CreateNetwork(configurator.Network{ID: "n1"}, serdes.Network)
+ assert.NoError(t, err)
+
+ e := echo.New()
+ testURLRoot := "/magma/v1/lte/:network_id/network_probe/tasks"
+ handlers := handlers.GetHandlers()
+ listNetworkProbeTasks := tests.GetHandlerByPathAndMethod(t, handlers, testURLRoot, obsidian.GET).HandlerFunc
+
+ tc := tests.Test{
+ Method: "GET",
+ URL: testURLRoot,
+ Handler: listNetworkProbeTasks,
+ ParamNames: []string{"network_id"},
+ ParamValues: []string{"n1"},
+ ExpectedStatus: 200,
+ ExpectedResult: tests.JSONMarshaler(map[string]*models.NetworkProbeTask{}),
+ }
+ tests.RunUnitTest(t, e, tc)
+
+ _, err = configurator.CreateEntities(
+ "n1",
+ []configurator.NetworkEntity{
+ {
+ Key: "IMSI1234",
+ Type: lte.NetworkProbeTaskEntityType,
+ Config: &models.NetworkProbeTaskDetails{
+ TargetID: "IMSI1234",
+ TargetType: "imsi",
+ DeliveryType: "events_only",
+ CorrelationID: 8674665223082154000,
+ },
+ },
+ {
+ Key: "IMSI1235",
+ Type: lte.NetworkProbeTaskEntityType,
+ Config: &models.NetworkProbeTaskDetails{
+ TargetID: "IMSI1235",
+ TargetType: "imsi",
+ DeliveryType: "all",
+ CorrelationID: 8674665223082154099,
+ },
+ },
+ },
+ serdes.Entity,
+ )
+ assert.NoError(t, err)
+
+ tc = tests.Test{
+ Method: "GET",
+ URL: testURLRoot,
+ Handler: listNetworkProbeTasks,
+ ParamNames: []string{"network_id"},
+ ParamValues: []string{"n1"},
+ ExpectedStatus: 200,
+ ExpectedResult: tests.JSONMarshaler(map[string]*models.NetworkProbeTask{
+ "IMSI1234": {
+ TaskID: "IMSI1234",
+ TaskDetails: &models.NetworkProbeTaskDetails{
+ TargetID: "IMSI1234",
+ TargetType: "imsi",
+ DeliveryType: "events_only",
+ CorrelationID: 8674665223082154000,
+ },
+ },
+ "IMSI1235": {
+ TaskID: "IMSI1235",
+ TaskDetails: &models.NetworkProbeTaskDetails{
+ TargetID: "IMSI1235",
+ TargetType: "imsi",
+ DeliveryType: "all",
+ CorrelationID: 8674665223082154099,
+ },
+ },
+ }),
+ }
+ tests.RunUnitTest(t, e, tc)
+}
+
+func TestGetNetworkProbeTask(t *testing.T) {
+ configuratorTestInit.StartTestService(t)
+ err := configurator.CreateNetwork(configurator.Network{ID: "n1"}, serdes.Network)
+ assert.NoError(t, err)
+
+ e := echo.New()
+ testURLRoot := "/magma/v1/lte/:network_id/network_probe/tasks/:task_id"
+ handlers := handlers.GetHandlers()
+ getNetworkProbeTask := tests.GetHandlerByPathAndMethod(t, handlers, testURLRoot, obsidian.GET).HandlerFunc
+
+ tc := tests.Test{
+ Method: "GET",
+ URL: testURLRoot,
+ Handler: getNetworkProbeTask,
+ ParamNames: []string{"network_id", "task_id"},
+ ParamValues: []string{"n1", "IMSI1234"},
+ ExpectedStatus: 404,
+ ExpectedError: "Not Found",
+ }
+ tests.RunUnitTest(t, e, tc)
+
+ _, err = configurator.CreateEntity(
+ "n1",
+ configurator.NetworkEntity{
+ Key: "IMSI1234",
+ Type: lte.NetworkProbeTaskEntityType,
+ Config: &models.NetworkProbeTaskDetails{
+ TargetID: "IMSI1234",
+ TargetType: "imsi",
+ DeliveryType: "events_only",
+ CorrelationID: 8674665223082154000,
+ },
+ },
+ serdes.Entity,
+ )
+ assert.NoError(t, err)
+
+ tc = tests.Test{
+ Method: "GET",
+ URL: testURLRoot,
+ Handler: getNetworkProbeTask,
+ ParamNames: []string{"network_id", "task_id"},
+ ParamValues: []string{"n1", "IMSI1234"},
+ ExpectedStatus: 200,
+ ExpectedResult: &models.NetworkProbeTask{
+ TaskID: "IMSI1234",
+ TaskDetails: &models.NetworkProbeTaskDetails{
+ TargetID: "IMSI1234",
+ TargetType: "imsi",
+ DeliveryType: "events_only",
+ CorrelationID: 8674665223082154000,
+ },
+ },
+ }
+ tests.RunUnitTest(t, e, tc)
+}
+
+func TestUpdateNetworkProbeTask(t *testing.T) {
+ configuratorTestInit.StartTestService(t)
+ err := configurator.CreateNetwork(configurator.Network{ID: "n1"}, serdes.Network)
+ assert.NoError(t, err)
+
+ e := echo.New()
+ testURLRoot := "/magma/v1/lte/:network_id/network_probe/tasks/:task_id"
+ handlers := handlers.GetHandlers()
+ updateNetworkProbeTask := tests.GetHandlerByPathAndMethod(t, handlers, testURLRoot, obsidian.PUT).HandlerFunc
+
+ // 404
+ payload := &models.NetworkProbeTask{
+ TaskID: "IMSI1234",
+ TaskDetails: &models.NetworkProbeTaskDetails{
+ TargetID: "IMSI1234",
+ TargetType: "imsi",
+ DeliveryType: "events_only",
+ CorrelationID: 8674665223082154000,
+ },
+ }
+
+ tc := tests.Test{
+ Method: "PUT",
+ URL: testURLRoot,
+ Handler: updateNetworkProbeTask,
+ Payload: payload,
+ ParamNames: []string{"network_id", "task_id"},
+ ParamValues: []string{"n1", "IMSI1234"},
+ ExpectedStatus: 500,
+ ExpectedError: "failed to load entity being updated: expected to load 1 ent for update, got 0",
+ }
+ tests.RunUnitTest(t, e, tc)
+
+ // Add the NetworkProbeTask
+ _, err = configurator.CreateEntity(
+ "n1",
+ configurator.NetworkEntity{
+ Key: "IMSI1234",
+ Type: lte.NetworkProbeTaskEntityType,
+ Config: &models.NetworkProbeTaskDetails{
+ TargetID: "IMSI1234",
+ TargetType: "imsi",
+ DeliveryType: "events_only",
+ CorrelationID: 8674665223082154000,
+ },
+ },
+ serdes.Entity,
+ )
+ assert.NoError(t, err)
+
+ tc = tests.Test{
+ Method: "PUT",
+ URL: testURLRoot,
+ Handler: updateNetworkProbeTask,
+ Payload: payload,
+ ParamNames: []string{"network_id", "task_id"},
+ ParamValues: []string{"n1", "IMSI1234"},
+ ExpectedStatus: 204,
+ }
+ tests.RunUnitTest(t, e, tc)
+
+ actual, err := configurator.LoadEntity("n1", lte.NetworkProbeTaskEntityType, "IMSI1234", configurator.FullEntityLoadCriteria(), serdes.Entity)
+ assert.NoError(t, err)
+ expected := configurator.NetworkEntity{
+ NetworkID: "n1",
+ Type: lte.NetworkProbeTaskEntityType,
+ Key: "IMSI1234",
+ Config: payload.TaskDetails,
+ GraphID: "2",
+ Version: 1,
+ }
+ assert.Equal(t, expected, actual)
+}
+
+func TestDeleteNetworkProbeTask(t *testing.T) {
+ configuratorTestInit.StartTestService(t)
+ err := configurator.CreateNetwork(configurator.Network{ID: "n1"}, serdes.Network)
+ assert.NoError(t, err)
+
+ e := echo.New()
+ testURLRoot := "/magma/v1/lte/:network_id/network_probe/tasks/:task_id"
+ handlers := handlers.GetHandlers()
+ deleteNetworkProbeTask := tests.GetHandlerByPathAndMethod(t, handlers, testURLRoot, obsidian.DELETE).HandlerFunc
+
+ _, err = configurator.CreateEntities(
+ "n1",
+ []configurator.NetworkEntity{
+ {
+ Key: "IMSI1234",
+ Type: lte.NetworkProbeTaskEntityType,
+ Config: &models.NetworkProbeTaskDetails{
+ TargetID: "IMSI1234",
+ TargetType: "imsi",
+ DeliveryType: "events_only",
+ CorrelationID: 8674665223082154000,
+ },
+ },
+ {
+ Key: "IMSI1235",
+ Type: lte.NetworkProbeTaskEntityType,
+ Config: &models.NetworkProbeTaskDetails{
+ TargetID: "IMSI1235",
+ TargetType: "imsi",
+ DeliveryType: "all",
+ CorrelationID: 8674665223082154099,
+ },
+ },
+ },
+ serdes.Entity,
+ )
+ assert.NoError(t, err)
+
+ tc := tests.Test{
+ Method: "DELETE",
+ URL: testURLRoot,
+ Handler: deleteNetworkProbeTask,
+ ParamNames: []string{"network_id", "task_id"},
+ ParamValues: []string{"n1", "IMSI1234"},
+ ExpectedStatus: 204,
+ }
+ tests.RunUnitTest(t, e, tc)
+
+ actual, _, err := configurator.LoadAllEntitiesOfType("n1", lte.NetworkProbeTaskEntityType, configurator.FullEntityLoadCriteria(), serdes.Entity)
+ assert.NoError(t, err)
+ assert.Equal(t, 1, len(actual))
+ expected := configurator.NetworkEntity{
+ NetworkID: "n1",
+ Type: lte.NetworkProbeTaskEntityType,
+ Key: "IMSI1235",
+ Config: &models.NetworkProbeTaskDetails{
+ TargetID: "IMSI1235",
+ TargetType: "imsi",
+ DeliveryType: "all",
+ CorrelationID: 8674665223082154099,
+ },
+ GraphID: "4",
+ Version: 0,
+ }
+ assert.Equal(t, expected, actual[0])
+}
+
+func TestCreateNetworkProbeDestination(t *testing.T) {
+ configuratorTestInit.StartTestService(t)
+ err := configurator.CreateNetwork(configurator.Network{ID: "n1"}, serdes.Network)
+ assert.NoError(t, err)
+
+ e := echo.New()
+ testURLRoot := "/magma/v1/lte/:network_id/network_probe/destinations"
+ handlers := handlers.GetHandlers()
+ createNetworkProbeDestination := tests.GetHandlerByPathAndMethod(t, handlers, testURLRoot, obsidian.POST).HandlerFunc
+
+ payload := &models.NetworkProbeDestination{
+ DestinationID: "test",
+ DestinationDetails: &models.NetworkProbeDestinationDetails{
+ DeliveryAddress: "127.0.0.1:4000",
+ DeliveryType: "all",
+ },
+ }
+
+ tc := tests.Test{
+ Method: "POST",
+ URL: testURLRoot,
+ Payload: payload,
+ Handler: createNetworkProbeDestination,
+ ParamNames: []string{"network_id"},
+ ParamValues: []string{"n1"},
+ ExpectedStatus: 201,
+ }
+ tests.RunUnitTest(t, e, tc)
+
+ actual, err := configurator.LoadEntity("n1", lte.NetworkProbeDestinationEntityType, "test", configurator.FullEntityLoadCriteria(), serdes.Entity)
+ assert.NoError(t, err)
+ expected := configurator.NetworkEntity{
+ NetworkID: "n1",
+ Type: lte.NetworkProbeDestinationEntityType,
+ Key: "test",
+ Config: payload.DestinationDetails,
+ GraphID: "2",
+ }
+ assert.Equal(t, expected, actual)
+}
+
+func TestListNetworkProbeDestinations(t *testing.T) {
+ configuratorTestInit.StartTestService(t)
+ err := configurator.CreateNetwork(configurator.Network{ID: "n1"}, serdes.Network)
+ assert.NoError(t, err)
+
+ e := echo.New()
+ testURLRoot := "/magma/v1/lte/:network_id/network_probe/destinations"
+ handlers := handlers.GetHandlers()
+ listNetworkProbeDestinations := tests.GetHandlerByPathAndMethod(t, handlers, testURLRoot, obsidian.GET).HandlerFunc
+
+ tc := tests.Test{
+ Method: "GET",
+ URL: testURLRoot,
+ Handler: listNetworkProbeDestinations,
+ ParamNames: []string{"network_id"},
+ ParamValues: []string{"n1"},
+ ExpectedStatus: 200,
+ ExpectedResult: tests.JSONMarshaler(map[string]*models.NetworkProbeDestination{}),
+ }
+ tests.RunUnitTest(t, e, tc)
+
+ _, err = configurator.CreateEntities(
+ "n1",
+ []configurator.NetworkEntity{
+ {
+ Key: "1111-2222-3333",
+ Type: lte.NetworkProbeDestinationEntityType,
+ Config: &models.NetworkProbeDestinationDetails{
+ DeliveryAddress: "127.0.0.1:4000",
+ DeliveryType: "all",
+ },
+ },
+ {
+ Key: "2222-3333-4444",
+ Type: lte.NetworkProbeDestinationEntityType,
+ Config: &models.NetworkProbeDestinationDetails{
+ DeliveryAddress: "127.0.0.1:4001",
+ DeliveryType: "all",
+ },
+ },
+ },
+ serdes.Entity,
+ )
+ assert.NoError(t, err)
+
+ tc = tests.Test{
+ Method: "GET",
+ URL: testURLRoot,
+ Handler: listNetworkProbeDestinations,
+ ParamNames: []string{"network_id"},
+ ParamValues: []string{"n1"},
+ ExpectedStatus: 200,
+ ExpectedResult: tests.JSONMarshaler(map[string]*models.NetworkProbeDestination{
+ "1111-2222-3333": {
+ DestinationID: "1111-2222-3333",
+ DestinationDetails: &models.NetworkProbeDestinationDetails{
+ DeliveryAddress: "127.0.0.1:4000",
+ DeliveryType: "all",
+ },
+ },
+ "2222-3333-4444": {
+ DestinationID: "2222-3333-4444",
+ DestinationDetails: &models.NetworkProbeDestinationDetails{
+ DeliveryAddress: "127.0.0.1:4001",
+ DeliveryType: "all",
+ },
+ },
+ }),
+ }
+ tests.RunUnitTest(t, e, tc)
+}
+
+func TestGetNetworkProbeDestination(t *testing.T) {
+ configuratorTestInit.StartTestService(t)
+ err := configurator.CreateNetwork(configurator.Network{ID: "n1"}, serdes.Network)
+ assert.NoError(t, err)
+
+ e := echo.New()
+ testURLRoot := "/magma/v1/lte/:network_id/network_probe/destinations/:destination_id"
+ handlers := handlers.GetHandlers()
+ getNetworkProbeDestination := tests.GetHandlerByPathAndMethod(t, handlers, testURLRoot, obsidian.GET).HandlerFunc
+
+ tc := tests.Test{
+ Method: "GET",
+ URL: testURLRoot,
+ Handler: getNetworkProbeDestination,
+ ParamNames: []string{"network_id", "destination_id"},
+ ParamValues: []string{"n1", "1111-2222-3333"},
+ ExpectedStatus: 404,
+ ExpectedError: "Not Found",
+ }
+ tests.RunUnitTest(t, e, tc)
+
+ _, err = configurator.CreateEntity(
+ "n1",
+ configurator.NetworkEntity{
+ Key: "1111-2222-3333",
+ Type: lte.NetworkProbeDestinationEntityType,
+ Config: &models.NetworkProbeDestinationDetails{
+ DeliveryAddress: "127.0.0.1:4000",
+ DeliveryType: "all",
+ },
+ },
+ serdes.Entity,
+ )
+ assert.NoError(t, err)
+
+ tc = tests.Test{
+ Method: "GET",
+ URL: testURLRoot,
+ Handler: getNetworkProbeDestination,
+ ParamNames: []string{"network_id", "destination_id"},
+ ParamValues: []string{"n1", "1111-2222-3333"},
+ ExpectedStatus: 200,
+ ExpectedResult: &models.NetworkProbeDestination{
+ DestinationID: "1111-2222-3333",
+ DestinationDetails: &models.NetworkProbeDestinationDetails{
+ DeliveryAddress: "127.0.0.1:4000",
+ DeliveryType: "all",
+ },
+ },
+ }
+ tests.RunUnitTest(t, e, tc)
+}
+
+func TestUpdateNetworkProbeDestination(t *testing.T) {
+ configuratorTestInit.StartTestService(t)
+ err := configurator.CreateNetwork(configurator.Network{ID: "n1"}, serdes.Network)
+ assert.NoError(t, err)
+
+ e := echo.New()
+ testURLRoot := "/magma/v1/lte/:network_id/network_probe/destinations/:destination_id"
+ handlers := handlers.GetHandlers()
+ updateNetworkProbeDestination := tests.GetHandlerByPathAndMethod(t, handlers, testURLRoot, obsidian.PUT).HandlerFunc
+
+ // 404
+ payload := &models.NetworkProbeDestination{
+ DestinationID: "1111-2222-3333",
+ DestinationDetails: &models.NetworkProbeDestinationDetails{
+ DeliveryAddress: "127.0.0.1:4000",
+ DeliveryType: "all",
+ },
+ }
+
+ tc := tests.Test{
+ Method: "PUT",
+ URL: testURLRoot,
+ Handler: updateNetworkProbeDestination,
+ Payload: payload,
+ ParamNames: []string{"network_id", "destination_id"},
+ ParamValues: []string{"n1", "1111-2222-3333"},
+ ExpectedStatus: 500,
+ ExpectedError: "failed to load entity being updated: expected to load 1 ent for update, got 0",
+ }
+ tests.RunUnitTest(t, e, tc)
+
+ // Add the NetworkProbeDestination
+ _, err = configurator.CreateEntity(
+ "n1",
+ configurator.NetworkEntity{
+ Key: "1111-2222-3333",
+ Type: lte.NetworkProbeDestinationEntityType,
+ Config: &models.NetworkProbeDestinationDetails{
+ DeliveryAddress: "127.0.0.1:4000",
+ DeliveryType: "all",
+ },
+ },
+ serdes.Entity,
+ )
+ assert.NoError(t, err)
+
+ tc = tests.Test{
+ Method: "PUT",
+ URL: testURLRoot,
+ Handler: updateNetworkProbeDestination,
+ Payload: payload,
+ ParamNames: []string{"network_id", "destination_id"},
+ ParamValues: []string{"n1", "1111-2222-3333"},
+ ExpectedStatus: 204,
+ }
+ tests.RunUnitTest(t, e, tc)
+
+ actual, err := configurator.LoadEntity("n1", lte.NetworkProbeDestinationEntityType, "1111-2222-3333", configurator.FullEntityLoadCriteria(), serdes.Entity)
+ assert.NoError(t, err)
+ expected := configurator.NetworkEntity{
+ NetworkID: "n1",
+ Type: lte.NetworkProbeDestinationEntityType,
+ Key: "1111-2222-3333",
+ Config: payload.DestinationDetails,
+ GraphID: "2",
+ Version: 1,
+ }
+ assert.Equal(t, expected, actual)
+}
+
+func TestDeleteNetworkProbeDestination(t *testing.T) {
+ configuratorTestInit.StartTestService(t)
+ err := configurator.CreateNetwork(configurator.Network{ID: "n1"}, serdes.Network)
+ assert.NoError(t, err)
+
+ e := echo.New()
+ testURLRoot := "/magma/v1/lte/:network_id/network_probe/destinations/:destination_id"
+ handlers := handlers.GetHandlers()
+ deleteNetworkProbeDestination := tests.GetHandlerByPathAndMethod(t, handlers, testURLRoot, obsidian.DELETE).HandlerFunc
+
+ _, err = configurator.CreateEntities(
+ "n1",
+ []configurator.NetworkEntity{
+ {
+ Key: "1111-2222-3333",
+ Type: lte.NetworkProbeDestinationEntityType,
+ Config: &models.NetworkProbeDestinationDetails{
+ DeliveryAddress: "127.0.0.1:4000",
+ DeliveryType: "events_only",
+ },
+ },
+ {
+ Key: "2222-3333-4444",
+ Type: lte.NetworkProbeDestinationEntityType,
+ Config: &models.NetworkProbeDestinationDetails{
+ DeliveryAddress: "127.0.0.1:4001",
+ DeliveryType: "all",
+ },
+ },
+ },
+ serdes.Entity,
+ )
+ assert.NoError(t, err)
+
+ tc := tests.Test{
+ Method: "DELETE",
+ URL: testURLRoot,
+ Handler: deleteNetworkProbeDestination,
+ ParamNames: []string{"network_id", "destination_id"},
+ ParamValues: []string{"n1", "1111-2222-3333"},
+ ExpectedStatus: 204,
+ }
+ tests.RunUnitTest(t, e, tc)
+
+ actual, _, err := configurator.LoadAllEntitiesOfType("n1", lte.NetworkProbeDestinationEntityType, configurator.FullEntityLoadCriteria(), serdes.Entity)
+ assert.NoError(t, err)
+ assert.Equal(t, 1, len(actual))
+ expected := configurator.NetworkEntity{
+ NetworkID: "n1",
+ Type: lte.NetworkProbeDestinationEntityType,
+ Key: "2222-3333-4444",
+ Config: &models.NetworkProbeDestinationDetails{
+ DeliveryAddress: "127.0.0.1:4001",
+ DeliveryType: "all",
+ },
+ GraphID: "4",
+ Version: 0,
+ }
+ assert.Equal(t, expected, actual[0])
+}
diff --git a/lte/cloud/go/services/nprobe/obsidian/models/conversion.go b/lte/cloud/go/services/nprobe/obsidian/models/conversion.go
new file mode 100644
index 000000000000..344ee1629224
--- /dev/null
+++ b/lte/cloud/go/services/nprobe/obsidian/models/conversion.go
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2020 The Magma Authors.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package models
+
+import (
+ "magma/lte/cloud/go/lte"
+ "magma/orc8r/cloud/go/services/configurator"
+)
+
+func (m *NetworkProbeTask) ToEntityUpdateCriteria() configurator.EntityUpdateCriteria {
+ return configurator.EntityUpdateCriteria{
+ Type: lte.NetworkProbeTaskEntityType,
+ Key: string(m.TaskID),
+ NewConfig: m.TaskDetails,
+ }
+}
+
+func (m *NetworkProbeTask) FromBackendModels(ent configurator.NetworkEntity) *NetworkProbeTask {
+ m.TaskID = NetworkProbeTaskID(ent.Key)
+ m.TaskDetails = ent.Config.(*NetworkProbeTaskDetails)
+ return m
+}
+
+func (m *NetworkProbeDestination) ToEntityUpdateCriteria() configurator.EntityUpdateCriteria {
+ return configurator.EntityUpdateCriteria{
+ Type: lte.NetworkProbeDestinationEntityType,
+ Key: string(m.DestinationID),
+ NewConfig: m.DestinationDetails,
+ }
+}
+
+func (m *NetworkProbeDestination) FromBackendModels(ent configurator.NetworkEntity) *NetworkProbeDestination {
+ m.DestinationID = NetworkProbeDestinationID(ent.Key)
+ m.DestinationDetails = ent.Config.(*NetworkProbeDestinationDetails)
+ return m
+}
diff --git a/lte/cloud/go/services/nprobe/obsidian/models/gen.go b/lte/cloud/go/services/nprobe/obsidian/models/gen.go
new file mode 100644
index 000000000000..e9a3b7bb83c1
--- /dev/null
+++ b/lte/cloud/go/services/nprobe/obsidian/models/gen.go
@@ -0,0 +1,15 @@
+/*
+ * Copyright 2020 The Magma Authors.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//go:generate swaggergen --target=swagger.v1.yml --root=$MAGMA_ROOT --config=$SWAGGER_V1_CONFIG
+package models
diff --git a/lte/cloud/go/services/nprobe/obsidian/models/network_probe_destination_details_swaggergen.go b/lte/cloud/go/services/nprobe/obsidian/models/network_probe_destination_details_swaggergen.go
new file mode 100644
index 000000000000..94187efc1e08
--- /dev/null
+++ b/lte/cloud/go/services/nprobe/obsidian/models/network_probe_destination_details_swaggergen.go
@@ -0,0 +1,118 @@
+// Code generated by go-swagger; DO NOT EDIT.
+
+package models
+
+// This file was generated by the swagger tool.
+// Editing this file might prove futile when you re-run the swagger generate command
+
+import (
+ "encoding/json"
+
+ strfmt "github.com/go-openapi/strfmt"
+
+ "github.com/go-openapi/errors"
+ "github.com/go-openapi/swag"
+ "github.com/go-openapi/validate"
+)
+
+// NetworkProbeDestinationDetails network probe destination details
+// swagger:model network_probe_destination_details
+type NetworkProbeDestinationDetails struct {
+
+ // delivery address
+ // Required: true
+ DeliveryAddress string `json:"delivery_address"`
+
+ // delivery type
+ // Required: true
+ // Enum: [all events_only]
+ DeliveryType string `json:"delivery_type"`
+}
+
+// Validate validates this network probe destination details
+func (m *NetworkProbeDestinationDetails) Validate(formats strfmt.Registry) error {
+ var res []error
+
+ if err := m.validateDeliveryAddress(formats); err != nil {
+ res = append(res, err)
+ }
+
+ if err := m.validateDeliveryType(formats); err != nil {
+ res = append(res, err)
+ }
+
+ if len(res) > 0 {
+ return errors.CompositeValidationError(res...)
+ }
+ return nil
+}
+
+func (m *NetworkProbeDestinationDetails) validateDeliveryAddress(formats strfmt.Registry) error {
+
+ if err := validate.RequiredString("delivery_address", "body", string(m.DeliveryAddress)); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+var networkProbeDestinationDetailsTypeDeliveryTypePropEnum []interface{}
+
+func init() {
+ var res []string
+ if err := json.Unmarshal([]byte(`["all","events_only"]`), &res); err != nil {
+ panic(err)
+ }
+ for _, v := range res {
+ networkProbeDestinationDetailsTypeDeliveryTypePropEnum = append(networkProbeDestinationDetailsTypeDeliveryTypePropEnum, v)
+ }
+}
+
+const (
+
+ // NetworkProbeDestinationDetailsDeliveryTypeAll captures enum value "all"
+ NetworkProbeDestinationDetailsDeliveryTypeAll string = "all"
+
+ // NetworkProbeDestinationDetailsDeliveryTypeEventsOnly captures enum value "events_only"
+ NetworkProbeDestinationDetailsDeliveryTypeEventsOnly string = "events_only"
+)
+
+// prop value enum
+func (m *NetworkProbeDestinationDetails) validateDeliveryTypeEnum(path, location string, value string) error {
+ if err := validate.Enum(path, location, value, networkProbeDestinationDetailsTypeDeliveryTypePropEnum); err != nil {
+ return err
+ }
+ return nil
+}
+
+func (m *NetworkProbeDestinationDetails) validateDeliveryType(formats strfmt.Registry) error {
+
+ if err := validate.RequiredString("delivery_type", "body", string(m.DeliveryType)); err != nil {
+ return err
+ }
+
+ // value enum
+ if err := m.validateDeliveryTypeEnum("delivery_type", "body", m.DeliveryType); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+// MarshalBinary interface implementation
+func (m *NetworkProbeDestinationDetails) MarshalBinary() ([]byte, error) {
+ if m == nil {
+ return nil, nil
+ }
+ return swag.WriteJSON(m)
+}
+
+// UnmarshalBinary interface implementation
+func (m *NetworkProbeDestinationDetails) UnmarshalBinary(b []byte) error {
+ var res NetworkProbeDestinationDetails
+ if err := swag.ReadJSON(b, &res); err != nil {
+ return err
+ }
+ *m = res
+ return nil
+}
diff --git a/lte/cloud/go/services/nprobe/obsidian/models/network_probe_destination_id_swaggergen.go b/lte/cloud/go/services/nprobe/obsidian/models/network_probe_destination_id_swaggergen.go
new file mode 100644
index 000000000000..559e050fa422
--- /dev/null
+++ b/lte/cloud/go/services/nprobe/obsidian/models/network_probe_destination_id_swaggergen.go
@@ -0,0 +1,19 @@
+// Code generated by go-swagger; DO NOT EDIT.
+
+package models
+
+// This file was generated by the swagger tool.
+// Editing this file might prove futile when you re-run the swagger generate command
+
+import (
+ strfmt "github.com/go-openapi/strfmt"
+)
+
+// NetworkProbeDestinationID network probe destination id
+// swagger:model network_probe_destination_id
+type NetworkProbeDestinationID string
+
+// Validate validates this network probe destination id
+func (m NetworkProbeDestinationID) Validate(formats strfmt.Registry) error {
+ return nil
+}
diff --git a/lte/cloud/go/services/nprobe/obsidian/models/network_probe_destination_swaggergen.go b/lte/cloud/go/services/nprobe/obsidian/models/network_probe_destination_swaggergen.go
new file mode 100644
index 000000000000..1d9870525907
--- /dev/null
+++ b/lte/cloud/go/services/nprobe/obsidian/models/network_probe_destination_swaggergen.go
@@ -0,0 +1,93 @@
+// Code generated by go-swagger; DO NOT EDIT.
+
+package models
+
+// This file was generated by the swagger tool.
+// Editing this file might prove futile when you re-run the swagger generate command
+
+import (
+ strfmt "github.com/go-openapi/strfmt"
+
+ "github.com/go-openapi/errors"
+ "github.com/go-openapi/swag"
+ "github.com/go-openapi/validate"
+)
+
+// NetworkProbeDestination Network Probe Destination
+// swagger:model network_probe_destination
+type NetworkProbeDestination struct {
+
+ // destination details
+ // Required: true
+ DestinationDetails *NetworkProbeDestinationDetails `json:"destination_details"`
+
+ // destination id
+ // Required: true
+ DestinationID NetworkProbeDestinationID `json:"destination_id"`
+}
+
+// Validate validates this network probe destination
+func (m *NetworkProbeDestination) Validate(formats strfmt.Registry) error {
+ var res []error
+
+ if err := m.validateDestinationDetails(formats); err != nil {
+ res = append(res, err)
+ }
+
+ if err := m.validateDestinationID(formats); err != nil {
+ res = append(res, err)
+ }
+
+ if len(res) > 0 {
+ return errors.CompositeValidationError(res...)
+ }
+ return nil
+}
+
+func (m *NetworkProbeDestination) validateDestinationDetails(formats strfmt.Registry) error {
+
+ if err := validate.Required("destination_details", "body", m.DestinationDetails); err != nil {
+ return err
+ }
+
+ if m.DestinationDetails != nil {
+ if err := m.DestinationDetails.Validate(formats); err != nil {
+ if ve, ok := err.(*errors.Validation); ok {
+ return ve.ValidateName("destination_details")
+ }
+ return err
+ }
+ }
+
+ return nil
+}
+
+func (m *NetworkProbeDestination) validateDestinationID(formats strfmt.Registry) error {
+
+ if err := m.DestinationID.Validate(formats); err != nil {
+ if ve, ok := err.(*errors.Validation); ok {
+ return ve.ValidateName("destination_id")
+ }
+ return err
+ }
+
+ return nil
+}
+
+// MarshalBinary interface implementation
+func (m *NetworkProbeDestination) MarshalBinary() ([]byte, error) {
+ if m == nil {
+ return nil, nil
+ }
+ return swag.WriteJSON(m)
+}
+
+// UnmarshalBinary interface implementation
+func (m *NetworkProbeDestination) UnmarshalBinary(b []byte) error {
+ var res NetworkProbeDestination
+ if err := swag.ReadJSON(b, &res); err != nil {
+ return err
+ }
+ *m = res
+ return nil
+}
diff --git a/lte/cloud/go/services/nprobe/obsidian/models/network_probe_task_details_swaggergen.go b/lte/cloud/go/services/nprobe/obsidian/models/network_probe_task_details_swaggergen.go
new file mode 100644
index 000000000000..c385e0d789cf
--- /dev/null
+++ b/lte/cloud/go/services/nprobe/obsidian/models/network_probe_task_details_swaggergen.go
@@ -0,0 +1,218 @@
+// Code generated by go-swagger; DO NOT EDIT.
+
+package models
+
+// This file was generated by the swagger tool.
+// Editing this file might prove futile when you re-run the swagger generate command
+
+import (
+ "encoding/json"
+
+ strfmt "github.com/go-openapi/strfmt"
+
+ "github.com/go-openapi/errors"
+ "github.com/go-openapi/swag"
+ "github.com/go-openapi/validate"
+)
+
+// NetworkProbeTaskDetails network probe task details
+// swagger:model network_probe_task_details
+type NetworkProbeTaskDetails struct {
+
+ // correlation id
+ CorrelationID uint64 `json:"correlation_id,omitempty"`
+
+ // delivery type
+ // Required: true
+ // Enum: [all events_only]
+ DeliveryType string `json:"delivery_type"`
+
+ // the duration in seconds after which the task will expire.
+ // Minimum: 0
+ Duration *int64 `json:"duration,omitempty"`
+
+ // target id
+ // Required: true
+ TargetID string `json:"target_id"`
+
+ // target type
+ // Required: true
+ // Enum: [imsi imei msisdn]
+ TargetType string `json:"target_type"`
+
+ // The timestamp in ISO 8601 format
+ // Format: date-time
+ Timestamp strfmt.DateTime `json:"timestamp,omitempty"`
+}
+
+// Validate validates this network probe task details
+func (m *NetworkProbeTaskDetails) Validate(formats strfmt.Registry) error {
+ var res []error
+
+ if err := m.validateDeliveryType(formats); err != nil {
+ res = append(res, err)
+ }
+
+ if err := m.validateDuration(formats); err != nil {
+ res = append(res, err)
+ }
+
+ if err := m.validateTargetID(formats); err != nil {
+ res = append(res, err)
+ }
+
+ if err := m.validateTargetType(formats); err != nil {
+ res = append(res, err)
+ }
+
+ if err := m.validateTimestamp(formats); err != nil {
+ res = append(res, err)
+ }
+
+ if len(res) > 0 {
+ return errors.CompositeValidationError(res...)
+ }
+ return nil
+}
+
+var networkProbeTaskDetailsTypeDeliveryTypePropEnum []interface{}
+
+func init() {
+ var res []string
+ if err := json.Unmarshal([]byte(`["all","events_only"]`), &res); err != nil {
+ panic(err)
+ }
+ for _, v := range res {
+ networkProbeTaskDetailsTypeDeliveryTypePropEnum = append(networkProbeTaskDetailsTypeDeliveryTypePropEnum, v)
+ }
+}
+
+const (
+
+ // NetworkProbeTaskDetailsDeliveryTypeAll captures enum value "all"
+ NetworkProbeTaskDetailsDeliveryTypeAll string = "all"
+
+ // NetworkProbeTaskDetailsDeliveryTypeEventsOnly captures enum value "events_only"
+ NetworkProbeTaskDetailsDeliveryTypeEventsOnly string = "events_only"
+)
+
+// prop value enum
+func (m *NetworkProbeTaskDetails) validateDeliveryTypeEnum(path, location string, value string) error {
+ if err := validate.Enum(path, location, value, networkProbeTaskDetailsTypeDeliveryTypePropEnum); err != nil {
+ return err
+ }
+ return nil
+}
+
+func (m *NetworkProbeTaskDetails) validateDeliveryType(formats strfmt.Registry) error {
+
+ if err := validate.RequiredString("delivery_type", "body", string(m.DeliveryType)); err != nil {
+ return err
+ }
+
+ // value enum
+ if err := m.validateDeliveryTypeEnum("delivery_type", "body", m.DeliveryType); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (m *NetworkProbeTaskDetails) validateDuration(formats strfmt.Registry) error {
+
+ if swag.IsZero(m.Duration) { // not required
+ return nil
+ }
+
+ if err := validate.MinimumInt("duration", "body", int64(*m.Duration), 0, false); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (m *NetworkProbeTaskDetails) validateTargetID(formats strfmt.Registry) error {
+
+ if err := validate.RequiredString("target_id", "body", string(m.TargetID)); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+var networkProbeTaskDetailsTypeTargetTypePropEnum []interface{}
+
+func init() {
+ var res []string
+ if err := json.Unmarshal([]byte(`["imsi","imei","msisdn"]`), &res); err != nil {
+ panic(err)
+ }
+ for _, v := range res {
+ networkProbeTaskDetailsTypeTargetTypePropEnum = append(networkProbeTaskDetailsTypeTargetTypePropEnum, v)
+ }
+}
+
+const (
+
+ // NetworkProbeTaskDetailsTargetTypeImsi captures enum value "imsi"
+ NetworkProbeTaskDetailsTargetTypeImsi string = "imsi"
+
+ // NetworkProbeTaskDetailsTargetTypeImei captures enum value "imei"
+ NetworkProbeTaskDetailsTargetTypeImei string = "imei"
+
+ // NetworkProbeTaskDetailsTargetTypeMsisdn captures enum value "msisdn"
+ NetworkProbeTaskDetailsTargetTypeMsisdn string = "msisdn"
+)
+
+// prop value enum
+func (m *NetworkProbeTaskDetails) validateTargetTypeEnum(path, location string, value string) error {
+ if err := validate.Enum(path, location, value, networkProbeTaskDetailsTypeTargetTypePropEnum); err != nil {
+ return err
+ }
+ return nil
+}
+
+func (m *NetworkProbeTaskDetails) validateTargetType(formats strfmt.Registry) error {
+
+ if err := validate.RequiredString("target_type", "body", string(m.TargetType)); err != nil {
+ return err
+ }
+
+ // value enum
+ if err := m.validateTargetTypeEnum("target_type", "body", m.TargetType); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (m *NetworkProbeTaskDetails) validateTimestamp(formats strfmt.Registry) error {
+
+ if swag.IsZero(m.Timestamp) { // not required
+ return nil
+ }
+
+ if err := validate.FormatOf("timestamp", "body", "date-time", m.Timestamp.String(), formats); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+// MarshalBinary interface implementation
+func (m *NetworkProbeTaskDetails) MarshalBinary() ([]byte, error) {
+ if m == nil {
+ return nil, nil
+ }
+ return swag.WriteJSON(m)
+}
+
+// UnmarshalBinary interface implementation
+func (m *NetworkProbeTaskDetails) UnmarshalBinary(b []byte) error {
+ var res NetworkProbeTaskDetails
+ if err := swag.ReadJSON(b, &res); err != nil {
+ return err
+ }
+ *m = res
+ return nil
+}
diff --git a/lte/cloud/go/services/nprobe/obsidian/models/network_probe_task_id_swaggergen.go b/lte/cloud/go/services/nprobe/obsidian/models/network_probe_task_id_swaggergen.go
new file mode 100644
index 000000000000..1e96e4d9d1b7
--- /dev/null
+++ b/lte/cloud/go/services/nprobe/obsidian/models/network_probe_task_id_swaggergen.go
@@ -0,0 +1,19 @@
+// Code generated by go-swagger; DO NOT EDIT.
+
+package models
+
+// This file was generated by the swagger tool.
+// Editing this file might prove futile when you re-run the swagger generate command
+
+import (
+ strfmt "github.com/go-openapi/strfmt"
+)
+
+// NetworkProbeTaskID network probe task id
+// swagger:model network_probe_task_id
+type NetworkProbeTaskID string
+
+// Validate validates this network probe task id
+func (m NetworkProbeTaskID) Validate(formats strfmt.Registry) error {
+ return nil
+}
diff --git a/lte/cloud/go/services/nprobe/obsidian/models/network_probe_task_swaggergen.go b/lte/cloud/go/services/nprobe/obsidian/models/network_probe_task_swaggergen.go
new file mode 100644
index 000000000000..fc8e59027ff8
--- /dev/null
+++ b/lte/cloud/go/services/nprobe/obsidian/models/network_probe_task_swaggergen.go
@@ -0,0 +1,93 @@
+// Code generated by go-swagger; DO NOT EDIT.
+
+package models
+
+// This file was generated by the swagger tool.
+// Editing this file might prove futile when you re-run the swagger generate command
+
+import (
+ strfmt "github.com/go-openapi/strfmt"
+
+ "github.com/go-openapi/errors"
+ "github.com/go-openapi/swag"
+ "github.com/go-openapi/validate"
+)
+
+// NetworkProbeTask Network Probe Task
+// swagger:model network_probe_task
+type NetworkProbeTask struct {
+
+ // task details
+ // Required: true
+ TaskDetails *NetworkProbeTaskDetails `json:"task_details"`
+
+ // task id
+ // Required: true
+ TaskID NetworkProbeTaskID `json:"task_id"`
+}
+
+// Validate validates this network probe task
+func (m *NetworkProbeTask) Validate(formats strfmt.Registry) error {
+ var res []error
+
+ if err := m.validateTaskDetails(formats); err != nil {
+ res = append(res, err)
+ }
+
+ if err := m.validateTaskID(formats); err != nil {
+ res = append(res, err)
+ }
+
+ if len(res) > 0 {
+ return errors.CompositeValidationError(res...)
+ }
+ return nil
+}
+
+func (m *NetworkProbeTask) validateTaskDetails(formats strfmt.Registry) error {
+
+ if err := validate.Required("task_details", "body", m.TaskDetails); err != nil {
+ return err
+ }
+
+ if m.TaskDetails != nil {
+ if err := m.TaskDetails.Validate(formats); err != nil {
+ if ve, ok := err.(*errors.Validation); ok {
+ return ve.ValidateName("task_details")
+ }
+ return err
+ }
+ }
+
+ return nil
+}
+
+func (m *NetworkProbeTask) validateTaskID(formats strfmt.Registry) error {
+
+ if err := m.TaskID.Validate(formats); err != nil {
+ if ve, ok := err.(*errors.Validation); ok {
+ return ve.ValidateName("task_id")
+ }
+ return err
+ }
+
+ return nil
+}
+
+// MarshalBinary interface implementation
+func (m *NetworkProbeTask) MarshalBinary() ([]byte, error) {
+ if m == nil {
+ return nil, nil
+ }
+ return swag.WriteJSON(m)
+}
+
+// UnmarshalBinary interface implementation
+func (m *NetworkProbeTask) UnmarshalBinary(b []byte) error {
+ var res NetworkProbeTask
+ if err := swag.ReadJSON(b, &res); err != nil {
+ return err
+ }
+ *m = res
+ return nil
+}
diff --git a/lte/cloud/go/services/nprobe/obsidian/models/serdes.go b/lte/cloud/go/services/nprobe/obsidian/models/serdes.go
new file mode 100644
index 000000000000..ae7219c1214c
--- /dev/null
+++ b/lte/cloud/go/services/nprobe/obsidian/models/serdes.go
@@ -0,0 +1,28 @@
+/*
+ Copyright 2020 The Magma Authors.
+
+ This source code is licensed under the BSD-style license found in the
+ LICENSE file in the root directory of this source tree.
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+package models
+
+import (
+ "magma/lte/cloud/go/lte"
+ "magma/orc8r/cloud/go/serde"
+ "magma/orc8r/cloud/go/services/configurator"
+)
+
+var (
+ // EntitySerdes contains the package's configurator network entity serdes
+ EntitySerdes = serde.NewRegistry(
+ configurator.NewNetworkEntityConfigSerde(lte.NetworkProbeTaskEntityType, &NetworkProbeTaskDetails{}),
+ configurator.NewNetworkEntityConfigSerde(lte.NetworkProbeDestinationEntityType, &NetworkProbeDestinationDetails{}),
+ )
+)
diff --git a/lte/cloud/go/services/nprobe/obsidian/models/swagger.v1.yml b/lte/cloud/go/services/nprobe/obsidian/models/swagger.v1.yml
new file mode 100644
index 000000000000..956dc9654b08
--- /dev/null
+++ b/lte/cloud/go/services/nprobe/obsidian/models/swagger.v1.yml
@@ -0,0 +1,294 @@
+---
+swagger: '2.0'
+
+magma-gen-meta:
+ go-package: magma/lte/cloud/go/services/nprobe/obsidian/models
+ dependencies:
+ - 'orc8r/cloud/go/models/swagger-common.yml'
+ - 'orc8r/cloud/go/services/orchestrator/obsidian/models/swagger.v1.yml'
+ temp-gen-filename: lte-nprobe-swagger.yml
+ output-dir: lte/cloud/go/services/nprobe/obsidian
+ types:
+ - go-struct-name: NetworkProbeTaskID
+ filename: network_probe_task_id_swaggergen.go
+ - go-struct-name: NetworkProbeTaskDetails
+ filename: network_probe_task_details_swaggergen.go
+ - go-struct-name: NetworkProbeTask
+ filename: network_probe_task_swaggergen.go
+ - go-struct-name: NetworkProbeDestinationID
+ filename: network_probe_destination_id_swaggergen.go
+ - go-struct-name: NetworkProbeDestinationDetails
+ filename: network_probe_destination_details_swaggergen.go
+ - go-struct-name: NetworkProbeDestination
+ filename: network_probe_destination_swaggergen.go
+
+info:
+ title: LTE Network Probes Management
+ description: LTE REST APIs
+ version: 1.0.0
+
+basePath: /magma/v1
+
+paths:
+ /lte/{network_id}/network_probe/tasks:
+ get:
+ summary: List NetworkProbeTask in the network
+ tags:
+ - Network Probes
+ parameters:
+ - $ref: './orc8r-swagger-common.yml#/parameters/network_id'
+ responses:
+ '200':
+ description: Provisioned NetworkProbeTasks
+ schema:
+ $ref: '#/definitions/network_probe_task'
+ default:
+ $ref: './orc8r-swagger-common.yml#/responses/UnexpectedError'
+ post:
+ summary: Add a new NetworkProbeTask to the network
+ tags:
+ - Network Probes
+ parameters:
+ - $ref: './orc8r-swagger-common.yml#/parameters/network_id'
+ - name: network_probe_task
+ in: body
+ required: true
+ schema:
+ $ref: '#/definitions/network_probe_task'
+ responses:
+ '201':
+ description: Success
+ default:
+ $ref: './orc8r-swagger-common.yml#/responses/UnexpectedError'
+
+ /lte/{network_id}/network_probe/tasks/{task_id}:
+ get:
+ summary: Retrieve the NetworkProbeTask info
+ tags:
+ - Network Probes
+ parameters:
+ - $ref: './orc8r-swagger-common.yml#/parameters/network_id'
+ - $ref: '#/parameters/task_id'
+ responses:
+ '200':
+ description: NetworkProbeTask Info
+ schema:
+ $ref: '#/definitions/network_probe_task'
+ default:
+ $ref: './orc8r-swagger-common.yml#/responses/UnexpectedError'
+ put:
+ summary: Update an existing NetworkProbeTask in the network
+ tags:
+ - Network Probes
+ parameters:
+ - $ref: './orc8r-swagger-common.yml#/parameters/network_id'
+ - $ref: '#/parameters/task_id'
+ - in: body
+ name: network_probe_task
+ description: New NetworkProbeTask configuration
+ required: true
+ schema:
+ $ref: '#/definitions/network_probe_task'
+ responses:
+ '204':
+ description: Success
+ default:
+ $ref: './orc8r-swagger-common.yml#/responses/UnexpectedError'
+ delete:
+ summary: Remove an NetworkProbeTask from the network
+ tags:
+ - Network Probes
+ parameters:
+ - $ref: './orc8r-swagger-common.yml#/parameters/network_id'
+ - $ref: '#/parameters/task_id'
+ responses:
+ '204':
+ description: Success
+ default:
+ $ref: './orc8r-swagger-common.yml#/responses/UnexpectedError'
+
+ /lte/{network_id}/network_probe/destinations:
+ get:
+ summary: List NetworkProbe Destinations in the network
+ tags:
+ - Network Probes
+ parameters:
+ - $ref: './orc8r-swagger-common.yml#/parameters/network_id'
+ responses:
+ '200':
+ description: Provisioned NetworkProbe Destinations
+ schema:
+ $ref: '#/definitions/network_probe_destination'
+ default:
+ $ref: './orc8r-swagger-common.yml#/responses/UnexpectedError'
+ post:
+ summary: Add a new NetworkProbeDestination to the network
+ tags:
+ - Network Probes
+ parameters:
+ - $ref: './orc8r-swagger-common.yml#/parameters/network_id'
+ - name: network_probe_destination
+ in: body
+ required: true
+ schema:
+ $ref: '#/definitions/network_probe_destination'
+ responses:
+ '201':
+ description: Success
+ default:
+ $ref: './orc8r-swagger-common.yml#/responses/UnexpectedError'
+
+ /lte/{network_id}/network_probe/destinations/{destination_id}:
+ get:
+ summary: Retrieve a NetworkProbe Destination
+ tags:
+ - Network Probes
+ parameters:
+ - $ref: './orc8r-swagger-common.yml#/parameters/network_id'
+ - $ref: '#/parameters/destination_id'
+ responses:
+ '200':
+ description: NetworkProbeDestination Info
+ schema:
+ $ref: '#/definitions/network_probe_destination'
+ default:
+ $ref: './orc8r-swagger-common.yml#/responses/UnexpectedError'
+ put:
+ summary: Update an existing NetworkProbe Destination in the network
+ tags:
+ - Network Probes
+ parameters:
+ - $ref: './orc8r-swagger-common.yml#/parameters/network_id'
+ - $ref: '#/parameters/destination_id'
+ - in: body
+ name: network_probe_destination
+ description: New NetworkProbeDestination configuration
+ required: true
+ schema:
+ $ref: '#/definitions/network_probe_destination'
+ responses:
+ '204':
+ description: Success
+ default:
+ $ref: './orc8r-swagger-common.yml#/responses/UnexpectedError'
+ delete:
+ summary: Remove a NetworkProbe Destination from the network
+ tags:
+ - Network Probes
+ parameters:
+ - $ref: './orc8r-swagger-common.yml#/parameters/network_id'
+ - $ref: '#/parameters/destination_id'
+ responses:
+ '204':
+ description: Success
+ default:
+ $ref: './orc8r-swagger-common.yml#/responses/UnexpectedError'
+
+parameters:
+ task_id:
+ in: path
+ name: task_id
+ description: Network Probe Task ID
+ required: true
+ type: string
+
+ destination_id:
+ in: path
+ name: destination_id
+ description: Network Probe Destination ID
+ required: true
+ type: string
+
+definitions:
+ network_probe_task:
+ description: Network Probe Task
+ type: object
+ required:
+ - task_id
+ - task_details
+ properties:
+ task_id:
+ $ref: "#/definitions/network_probe_task_id"
+ task_details:
+ $ref: '#/definitions/network_probe_task_details'
+
+ network_probe_task_id:
+ type: string
+ x-nullable: false
+ example: 'imsi1023001'
+
+ network_probe_task_details:
+ type: object
+ required:
+ - target_id
+ - target_type
+ - delivery_type
+ properties:
+ target_id:
+ type: string
+ x-nullable: false
+ target_type:
+ type: string
+ x-nullable: false
+ enum:
+ - 'imsi'
+ - 'imei'
+ - 'msisdn'
+ example: 'imsi'
+ delivery_type:
+ type: string
+ x-nullable: false
+ enum:
+ - 'all'
+ - 'events_only'
+ example: 'events_only'
+ correlation_id:
+ type: integer
+ format: uint64
+ example: 605394647632969700
+ duration:
+ type: integer
+ default: 0
+ minimum: 0
+ example: 300
+ description: the duration in seconds after which the task will expire.
+ timestamp:
+ type: string
+ format: date-time
+ example: 2020-03-11T00:36:59.65Z
+ description: The timestamp in ISO 8601 format
+
+ network_probe_destination:
+ description: Network Probe Destination
+ type: object
+ required:
+ - destination_id
+ - destination_details
+ properties:
+ destination_id:
+ $ref: '#/definitions/network_probe_destination_id'
+ destination_details:
+ $ref: '#/definitions/network_probe_destination_details'
+
+ network_probe_destination_id:
+ type: string
+ x-nullable: false
+ example: 'xxxx-yyyy-zzzz'
+
+ network_probe_destination_details:
+ type: object
+ required:
+ - delivery_type
+ - delivery_address
+ properties:
+ delivery_type:
+ type: string
+ x-nullable: false
+ enum:
+ - 'all'
+ - 'events_only'
+ example: 'events_only'
+ delivery_address:
+ type: string
+ x-nullable: false
+ example: '127.0.0.1:4040'
diff --git a/lte/cloud/go/services/nprobe/obsidian/models/validate.go b/lte/cloud/go/services/nprobe/obsidian/models/validate.go
new file mode 100644
index 000000000000..5358471cff6c
--- /dev/null
+++ b/lte/cloud/go/services/nprobe/obsidian/models/validate.go
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2020 The Magma Authors.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package models
+
+import (
+ strfmt "github.com/go-openapi/strfmt"
+)
+
+func (m *NetworkProbeTask) ValidateModel() error {
+ return m.Validate(strfmt.Default)
+}
+
+func (m *NetworkProbeDestination) ValidateModel() error {
+ return m.Validate(strfmt.Default)
+}
diff --git a/lte/cloud/go/services/subscriberdb/servicers/subscriberdb_servicer.go b/lte/cloud/go/services/subscriberdb/servicers/subscriberdb_servicer.go
new file mode 100644
index 000000000000..48390a7a9f3b
--- /dev/null
+++ b/lte/cloud/go/services/subscriberdb/servicers/subscriberdb_servicer.go
@@ -0,0 +1,193 @@
+/*
+Copyright 2020 The Magma Authors.
+
+This source code is licensed under the BSD-style license found in the
+LICENSE file in the root directory of this source tree.
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package servicers
+
+import (
+ "context"
+ "sort"
+
+ "github.com/pkg/errors"
+ "google.golang.org/grpc/codes"
+ "google.golang.org/grpc/status"
+
+ "magma/lte/cloud/go/lte"
+ lte_protos "magma/lte/cloud/go/protos"
+ "magma/lte/cloud/go/serdes"
+ lte_models "magma/lte/cloud/go/services/lte/obsidian/models"
+ "magma/lte/cloud/go/services/subscriberdb/obsidian/models"
+ "magma/orc8r/cloud/go/services/configurator"
+ "magma/orc8r/lib/go/protos"
+)
+
+type subscriberdbServicer struct{}
+
+const defaultSubProfile = "default"
+
+func NewSubscriberdbServicer() lte_protos.SubscriberDBCloudServer {
+ return &subscriberdbServicer{}
+}
+
+// ListSubscribers returns a page of subscribers and a token to be used on
+// subsequent requests. The page token specified in the request is used to
+// determine the first subscriber to include in the page. The page size
+// specified in the request determines the maximum number of entities to
+// return. If no page size is specified, the maximum size configured in the
+// configurator service will be returned.
+func (s *subscriberdbServicer) ListSubscribers(ctx context.Context, req *lte_protos.ListSubscribersRequest) (*lte_protos.ListSubscribersResponse, error) {
+ gateway := protos.GetClientGateway(ctx)
+ if gateway == nil {
+ return nil, status.Errorf(codes.PermissionDenied, "missing gateway identity")
+ }
+ if !gateway.Registered() {
+ return nil, status.Errorf(codes.PermissionDenied, "gateway is not registered")
+ }
+ networkID := gateway.NetworkId
+ gatewayID := gateway.LogicalId
+ lc := configurator.EntityLoadCriteria{
+ PageSize: req.PageSize,
+ PageToken: req.PageToken,
+ LoadConfig: true,
+ LoadAssocsToThis: true,
+ LoadAssocsFromThis: true,
+ }
+ subEnts, nextToken, err := configurator.LoadAllEntitiesOfType(
+ networkID, lte.SubscriberEntityType, lc, serdes.Entity,
+ )
+ if err != nil {
+ return nil, errors.Wrapf(err, "load subscribers in network of gateway %s", networkID)
+ }
+ lteGateway, err := configurator.LoadEntity(
+ networkID, lte.CellularGatewayEntityType, gatewayID,
+ configurator.EntityLoadCriteria{LoadAssocsFromThis: true},
+ serdes.Entity,
+ )
+ if err != nil {
+ return nil, errors.Wrapf(err, "load cellular gateway for gateway %s", gatewayID)
+ }
+ apnsByName, apnResourcesByAPN, err := loadAPNs(lteGateway)
+ if err != nil {
+ return nil, err
+ }
+
+ subProtos := make([]*lte_protos.SubscriberData, 0, len(subEnts))
+ for _, sub := range subEnts {
+ subProto, err := convertSubEntsToProtos(sub, apnsByName, apnResourcesByAPN)
+ if err != nil {
+ return nil, err
+ }
+ subProto.NetworkId = &protos.NetworkID{Id: networkID}
+ subProtos = append(subProtos, subProto)
+ }
+ listRes := <e_protos.ListSubscribersResponse{
+ Subscribers: subProtos,
+ NextPageToken: nextToken,
+ }
+ return listRes, nil
+}
+
+func loadAPNs(gateway configurator.NetworkEntity) (map[string]*lte_models.ApnConfiguration, lte_models.ApnResources, error) {
+ apns, _, err := configurator.LoadAllEntitiesOfType(
+ gateway.NetworkID, lte.APNEntityType,
+ configurator.EntityLoadCriteria{LoadConfig: true},
+ serdes.Entity,
+ )
+ if err != nil {
+ return nil, nil, err
+ }
+ apnsByName := map[string]*lte_models.ApnConfiguration{}
+ for _, ent := range apns {
+ apnsByName[ent.Key] = ent.Config.(*lte_models.ApnConfiguration)
+ }
+
+ apnResources, err := lte_models.LoadAPNResources(gateway.NetworkID, gateway.Associations.Filter(lte.APNResourceEntityType).Keys())
+ if err != nil {
+ return nil, nil, err
+ }
+
+ return apnsByName, apnResources, nil
+}
+
+func convertSubEntsToProtos(ent configurator.NetworkEntity, apnConfigs map[string]*lte_models.ApnConfiguration, apnResources lte_models.ApnResources) (*lte_protos.SubscriberData, error) {
+ subData := <e_protos.SubscriberData{}
+ t, err := lte_protos.SidProto(ent.Key)
+ if err != nil {
+ return nil, err
+ }
+
+ subData.Sid = t
+ if ent.Config == nil {
+ return subData, nil
+ }
+
+ cfg := ent.Config.(*models.SubscriberConfig)
+ subData.Lte = <e_protos.LTESubscription{
+ State: lte_protos.LTESubscription_LTESubscriptionState(lte_protos.LTESubscription_LTESubscriptionState_value[cfg.Lte.State]),
+ AuthAlgo: lte_protos.LTESubscription_LTEAuthAlgo(lte_protos.LTESubscription_LTEAuthAlgo_value[cfg.Lte.AuthAlgo]),
+ AuthKey: cfg.Lte.AuthKey,
+ AuthOpc: cfg.Lte.AuthOpc,
+ }
+
+ if cfg.Lte.SubProfile != "" {
+ subData.SubProfile = string(cfg.Lte.SubProfile)
+ } else {
+ subData.SubProfile = defaultSubProfile
+ }
+
+ for _, assoc := range ent.ParentAssociations {
+ if assoc.Type == lte.BaseNameEntityType {
+ subData.Lte.AssignedBaseNames = append(subData.Lte.AssignedBaseNames, assoc.Key)
+ } else if assoc.Type == lte.PolicyRuleEntityType {
+ subData.Lte.AssignedPolicies = append(subData.Lte.AssignedPolicies, assoc.Key)
+ }
+ }
+
+ // Construct the non-3gpp profile
+ non3gpp := <e_protos.Non3GPPUserProfile{
+ ApnConfig: make([]*lte_protos.APNConfiguration, 0, len(ent.Associations)),
+ }
+ for _, assoc := range ent.Associations {
+ apnConfig, apnFound := apnConfigs[assoc.Key]
+ if !apnFound {
+ continue
+ }
+ var apnResource *lte_protos.APNConfiguration_APNResource
+ if apnResourceModel, ok := apnResources[assoc.Key]; ok {
+ apnResource = apnResourceModel.ToProto()
+ }
+ apnProto := <e_protos.APNConfiguration{
+ ServiceSelection: assoc.Key,
+ Ambr: <e_protos.AggregatedMaximumBitrate{
+ MaxBandwidthUl: *(apnConfig.Ambr.MaxBandwidthUl),
+ MaxBandwidthDl: *(apnConfig.Ambr.MaxBandwidthDl),
+ },
+ QosProfile: <e_protos.APNConfiguration_QoSProfile{
+ ClassId: *(apnConfig.QosProfile.ClassID),
+ PriorityLevel: *(apnConfig.QosProfile.PriorityLevel),
+ PreemptionCapability: *(apnConfig.QosProfile.PreemptionCapability),
+ PreemptionVulnerability: *(apnConfig.QosProfile.PreemptionVulnerability),
+ },
+ Resource: apnResource,
+ }
+ if staticIP, found := cfg.StaticIps[assoc.Key]; found {
+ apnProto.AssignedStaticIp = string(staticIP)
+ }
+ non3gpp.ApnConfig = append(non3gpp.ApnConfig, apnProto)
+ }
+ sort.Slice(non3gpp.ApnConfig, func(i, j int) bool {
+ return non3gpp.ApnConfig[i].ServiceSelection < non3gpp.ApnConfig[j].ServiceSelection
+ })
+ subData.Non_3Gpp = non3gpp
+
+ return subData, nil
+}
diff --git a/lte/cloud/go/services/subscriberdb/servicers/subscriberdb_servicer_test.go b/lte/cloud/go/services/subscriberdb/servicers/subscriberdb_servicer_test.go
new file mode 100644
index 000000000000..1cc4e4a8627e
--- /dev/null
+++ b/lte/cloud/go/services/subscriberdb/servicers/subscriberdb_servicer_test.go
@@ -0,0 +1,302 @@
+/*
+Copyright 2020 The Magma Authors.
+
+This source code is licensed under the BSD-style license found in the
+LICENSE file in the root directory of this source tree.
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package servicers_test
+
+import (
+ "context"
+ "encoding/base64"
+ "testing"
+
+ "magma/lte/cloud/go/lte"
+ lte_protos "magma/lte/cloud/go/protos"
+ "magma/lte/cloud/go/serdes"
+ lte_models "magma/lte/cloud/go/services/lte/obsidian/models"
+ lte_test_init "magma/lte/cloud/go/services/lte/test_init"
+ "magma/lte/cloud/go/services/subscriberdb/obsidian/models"
+ "magma/lte/cloud/go/services/subscriberdb/servicers"
+ "magma/orc8r/cloud/go/orc8r"
+ "magma/orc8r/cloud/go/services/configurator"
+ configurator_storage "magma/orc8r/cloud/go/services/configurator/storage"
+ configurator_test_init "magma/orc8r/cloud/go/services/configurator/test_init"
+ "magma/orc8r/cloud/go/storage"
+ "magma/orc8r/lib/go/protos"
+
+ "github.com/go-openapi/swag"
+ "github.com/golang/protobuf/proto"
+ "github.com/stretchr/testify/assert"
+)
+
+func TestSubscriberdbCloudServicer(t *testing.T) {
+ lte_test_init.StartTestService(t)
+ configurator_test_init.StartTestService(t)
+
+ servicer := servicers.NewSubscriberdbServicer()
+ err := configurator.CreateNetwork(configurator.Network{ID: "n1"}, serdes.Network)
+ assert.NoError(t, err)
+ _, err = configurator.CreateEntity("n1", configurator.NetworkEntity{Type: orc8r.MagmadGatewayType, Key: "g1", PhysicalID: "hw1"}, serdes.Entity)
+ assert.NoError(t, err)
+ gw, err := configurator.CreateEntity("n1", configurator.NetworkEntity{Type: lte.CellularGatewayEntityType, Key: "g1"}, serdes.Entity)
+ assert.NoError(t, err)
+
+ id := protos.NewGatewayIdentity("hw1", "n1", "g1")
+ ctx := id.NewContextWithIdentity(context.Background())
+
+ // 2 subs without a profile on the backend (should fill as "default"), the
+ // other inactive with a sub profile
+ // 2 APNs active for the active sub, 1 with an assigned static IP and the
+ // other without
+ _, err = configurator.CreateEntities(
+ "n1",
+ []configurator.NetworkEntity{
+ {
+ Type: lte.APNEntityType, Key: "apn1",
+ Config: <e_models.ApnConfiguration{
+ Ambr: <e_models.AggregatedMaximumBitrate{
+ MaxBandwidthDl: swag.Uint32(42),
+ MaxBandwidthUl: swag.Uint32(100),
+ },
+ QosProfile: <e_models.QosProfile{
+ ClassID: swag.Int32(1),
+ PreemptionCapability: swag.Bool(true),
+ PreemptionVulnerability: swag.Bool(true),
+ PriorityLevel: swag.Uint32(1),
+ },
+ },
+ },
+ {
+ Type: lte.APNEntityType, Key: "apn2",
+ Config: <e_models.ApnConfiguration{
+ Ambr: <e_models.AggregatedMaximumBitrate{
+ MaxBandwidthDl: swag.Uint32(42),
+ MaxBandwidthUl: swag.Uint32(100),
+ },
+ QosProfile: <e_models.QosProfile{
+ ClassID: swag.Int32(2),
+ PreemptionCapability: swag.Bool(false),
+ PreemptionVulnerability: swag.Bool(false),
+ PriorityLevel: swag.Uint32(2),
+ },
+ },
+ },
+ {
+ Type: lte.SubscriberEntityType, Key: "IMSI12345",
+ Config: &models.SubscriberConfig{
+ Lte: &models.LteSubscription{
+ State: "ACTIVE",
+ AuthKey: []byte("\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22"),
+ AuthOpc: []byte("\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22"),
+ },
+ StaticIps: models.SubscriberStaticIps{"apn1": "192.168.100.1"},
+ },
+ Associations: []storage.TypeAndKey{{Type: lte.APNEntityType, Key: "apn1"}, {Type: lte.APNEntityType, Key: "apn2"}},
+ },
+ {Type: lte.SubscriberEntityType, Key: "IMSI67890", Config: &models.SubscriberConfig{Lte: &models.LteSubscription{State: "INACTIVE", SubProfile: "foo"}}},
+ {Type: lte.SubscriberEntityType, Key: "IMSI99999", Config: &models.SubscriberConfig{Lte: &models.LteSubscription{State: "INACTIVE", SubProfile: "foo"}}},
+ },
+ serdes.Entity,
+ )
+ assert.NoError(t, err)
+
+ // Fetch first page of subscribers
+ expectedProtos := []*lte_protos.SubscriberData{
+ {
+ Sid: <e_protos.SubscriberID{Id: "12345", Type: lte_protos.SubscriberID_IMSI},
+ Lte: <e_protos.LTESubscription{
+ State: lte_protos.LTESubscription_ACTIVE,
+ AuthKey: []byte("\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22"),
+ AuthOpc: []byte("\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22"),
+ },
+ NetworkId: &protos.NetworkID{Id: "n1"},
+ SubProfile: "default",
+ Non_3Gpp: <e_protos.Non3GPPUserProfile{
+ ApnConfig: []*lte_protos.APNConfiguration{
+ {
+ ServiceSelection: "apn1",
+ QosProfile: <e_protos.APNConfiguration_QoSProfile{
+ ClassId: 1,
+ PriorityLevel: 1,
+ PreemptionCapability: true,
+ PreemptionVulnerability: true,
+ },
+ Ambr: <e_protos.AggregatedMaximumBitrate{
+ MaxBandwidthUl: 100,
+ MaxBandwidthDl: 42,
+ },
+ AssignedStaticIp: "192.168.100.1",
+ },
+ {
+ ServiceSelection: "apn2",
+ QosProfile: <e_protos.APNConfiguration_QoSProfile{
+ ClassId: 2,
+ PriorityLevel: 2,
+ PreemptionCapability: false,
+ PreemptionVulnerability: false,
+ },
+ Ambr: <e_protos.AggregatedMaximumBitrate{
+ MaxBandwidthUl: 100,
+ MaxBandwidthDl: 42,
+ },
+ },
+ },
+ },
+ },
+ {
+ Sid: <e_protos.SubscriberID{Id: "67890", Type: lte_protos.SubscriberID_IMSI},
+ Lte: <e_protos.LTESubscription{State: lte_protos.LTESubscription_INACTIVE, AuthKey: []byte{}},
+ Non_3Gpp: <e_protos.Non3GPPUserProfile{ApnConfig: []*lte_protos.APNConfiguration{}},
+ NetworkId: &protos.NetworkID{Id: "n1"},
+ SubProfile: "foo",
+ },
+ }
+
+ // Fetch first page of subscribers
+ req := <e_protos.ListSubscribersRequest{
+ PageSize: 2,
+ PageToken: "",
+ }
+ res, err := servicer.ListSubscribers(ctx, req)
+ token := &configurator_storage.EntityPageToken{
+ LastIncludedEntity: "IMSI67890",
+ }
+ expectedToken := serializeToken(t, token)
+ assert.NoError(t, err)
+ assert.Equal(t, expectedProtos, res.Subscribers)
+ assert.Equal(t, expectedToken, res.NextPageToken)
+
+ expectedProtos2 := []*lte_protos.SubscriberData{
+ {
+ Sid: <e_protos.SubscriberID{Id: "99999", Type: lte_protos.SubscriberID_IMSI},
+ Lte: <e_protos.LTESubscription{State: lte_protos.LTESubscription_INACTIVE, AuthKey: []byte{}},
+ Non_3Gpp: <e_protos.Non3GPPUserProfile{ApnConfig: []*lte_protos.APNConfiguration{}},
+ NetworkId: &protos.NetworkID{Id: "n1"},
+ SubProfile: "foo",
+ },
+ }
+
+ // Fetch final page of subscribers
+ req = <e_protos.ListSubscribersRequest{
+ PageSize: 2,
+ PageToken: res.NextPageToken,
+ }
+ res, err = servicer.ListSubscribers(ctx, req)
+ assert.NoError(t, err)
+ assert.Equal(t, expectedProtos2, res.Subscribers)
+ assert.Equal(t, "", res.NextPageToken)
+
+ // Create policies and base name associated to sub
+ _, err = configurator.CreateEntities(
+ "n1",
+ []configurator.NetworkEntity{
+ {
+ Type: lte.BaseNameEntityType, Key: "bn1",
+ Associations: []storage.TypeAndKey{{Type: lte.SubscriberEntityType, Key: "IMSI12345"}},
+ },
+ {
+ Type: lte.PolicyRuleEntityType, Key: "r1",
+ Associations: []storage.TypeAndKey{{Type: lte.SubscriberEntityType, Key: "IMSI12345"}},
+ },
+ {
+ Type: lte.PolicyRuleEntityType, Key: "r2",
+ Associations: []storage.TypeAndKey{{Type: lte.SubscriberEntityType, Key: "IMSI12345"}},
+ },
+ },
+ serdes.Entity,
+ )
+ assert.NoError(t, err)
+
+ expectedProtos[0].Lte.AssignedPolicies = []string{"r1", "r2"}
+ expectedProtos[0].Lte.AssignedBaseNames = []string{"bn1"}
+
+ req = <e_protos.ListSubscribersRequest{
+ PageSize: 2,
+ PageToken: "",
+ }
+ res, err = servicer.ListSubscribers(ctx, req)
+ assert.NoError(t, err)
+ assert.Equal(t, expectedProtos, res.Subscribers)
+ assert.Equal(t, expectedToken, res.NextPageToken)
+
+ // Create gateway-specific APN configuration
+ var writes []configurator.EntityWriteOperation
+ writes = append(writes, configurator.NetworkEntity{
+ NetworkID: "n1",
+ Type: lte.APNResourceEntityType,
+ Key: "resource1",
+ Config: <e_models.ApnResource{
+ ApnName: "apn1",
+ GatewayIP: "172.16.254.1",
+ GatewayMac: "00:0a:95:9d:68:16",
+ ID: "resource1",
+ VlanID: 42,
+ },
+ Associations: storage.TKs{{Type: lte.APNEntityType, Key: "apn1"}},
+ })
+ writes = append(writes, configurator.EntityUpdateCriteria{
+ Type: lte.CellularGatewayEntityType,
+ Key: gw.Key,
+ AssociationsToAdd: storage.TKs{{Type: lte.APNResourceEntityType, Key: "resource1"}},
+ })
+ err = configurator.WriteEntities("n1", writes, serdes.Entity)
+ assert.NoError(t, err)
+
+ expectedProtos[0].Non_3Gpp.ApnConfig[0].Resource = <e_protos.APNConfiguration_APNResource{
+ ApnName: "apn1",
+ GatewayIp: "172.16.254.1",
+ GatewayMac: "00:0a:95:9d:68:16",
+ VlanId: 42,
+ }
+
+ res, err = servicer.ListSubscribers(ctx, req)
+ assert.NoError(t, err)
+ assert.Equal(t, expectedProtos, res.Subscribers)
+ assert.Equal(t, expectedToken, res.NextPageToken)
+
+ // Create 8 more subscribers to test max page size
+ _, err = configurator.CreateEntities(
+ "n1",
+ []configurator.NetworkEntity{
+ {Type: lte.SubscriberEntityType, Key: "IMSI99991", Config: &models.SubscriberConfig{Lte: &models.LteSubscription{State: "INACTIVE", SubProfile: "foo"}}},
+ {Type: lte.SubscriberEntityType, Key: "IMSI99992", Config: &models.SubscriberConfig{Lte: &models.LteSubscription{State: "INACTIVE", SubProfile: "foo"}}},
+ {Type: lte.SubscriberEntityType, Key: "IMSI99993", Config: &models.SubscriberConfig{Lte: &models.LteSubscription{State: "INACTIVE", SubProfile: "foo"}}},
+ {Type: lte.SubscriberEntityType, Key: "IMSI99994", Config: &models.SubscriberConfig{Lte: &models.LteSubscription{State: "INACTIVE", SubProfile: "foo"}}},
+ {Type: lte.SubscriberEntityType, Key: "IMSI99995", Config: &models.SubscriberConfig{Lte: &models.LteSubscription{State: "INACTIVE", SubProfile: "foo"}}},
+ {Type: lte.SubscriberEntityType, Key: "IMSI99996", Config: &models.SubscriberConfig{Lte: &models.LteSubscription{State: "INACTIVE", SubProfile: "foo"}}},
+ {Type: lte.SubscriberEntityType, Key: "IMSI99997", Config: &models.SubscriberConfig{Lte: &models.LteSubscription{State: "INACTIVE", SubProfile: "foo"}}},
+ {Type: lte.SubscriberEntityType, Key: "IMSI99998", Config: &models.SubscriberConfig{Lte: &models.LteSubscription{State: "INACTIVE", SubProfile: "foo"}}},
+ },
+ serdes.Entity,
+ )
+ assert.NoError(t, err)
+
+ // max page size for the configurator test service is 10 entities
+ // Ensure when page size specified is 0, max size is returned (10/11 subs)
+ req = <e_protos.ListSubscribersRequest{
+ PageSize: 0,
+ PageToken: "",
+ }
+ res, err = servicer.ListSubscribers(ctx, req)
+ token = &configurator_storage.EntityPageToken{
+ LastIncludedEntity: "IMSI99998",
+ }
+ expectedToken = serializeToken(t, token)
+ assert.NoError(t, err)
+ assert.Equal(t, 10, len(res.Subscribers))
+ assert.Equal(t, expectedToken, res.NextPageToken)
+}
+
+func serializeToken(t *testing.T, token *configurator_storage.EntityPageToken) string {
+ marshalledToken, err := proto.Marshal(token)
+ assert.NoError(t, err)
+ return base64.StdEncoding.EncodeToString(marshalledToken)
+}
diff --git a/lte/cloud/go/services/subscriberdb/subscriberdb/main.go b/lte/cloud/go/services/subscriberdb/subscriberdb/main.go
index 0dd730947412..3ffb72f24719 100644
--- a/lte/cloud/go/services/subscriberdb/subscriberdb/main.go
+++ b/lte/cloud/go/services/subscriberdb/subscriberdb/main.go
@@ -15,6 +15,7 @@ package main
import (
"magma/lte/cloud/go/lte"
+ lte_protos "magma/lte/cloud/go/protos"
"magma/lte/cloud/go/services/subscriberdb"
"magma/lte/cloud/go/services/subscriberdb/obsidian/handlers"
"magma/lte/cloud/go/services/subscriberdb/protos"
@@ -57,6 +58,7 @@ func main() {
obsidian.AttachHandlers(srv.EchoServer, handlers.GetHandlers())
protos.RegisterSubscriberLookupServer(srv.GrpcServer, servicers.NewLookupServicer(fact, ipStore))
state_protos.RegisterIndexerServer(srv.GrpcServer, servicers.NewIndexerServicer())
+ lte_protos.RegisterSubscriberDBCloudServer(srv.GrpcServer, servicers.NewSubscriberdbServicer())
swagger_protos.RegisterSwaggerSpecServer(srv.GrpcServer, swagger.NewSpecServicerFromFile(subscriberdb.ServiceName))
diff --git a/lte/cloud/go/services/subscriberdb/test_init/test_service_init.go b/lte/cloud/go/services/subscriberdb/test_init/test_service_init.go
index 1d8559f6300f..b1ef84026670 100644
--- a/lte/cloud/go/services/subscriberdb/test_init/test_service_init.go
+++ b/lte/cloud/go/services/subscriberdb/test_init/test_service_init.go
@@ -17,6 +17,7 @@ import (
"testing"
"magma/lte/cloud/go/lte"
+ lte_protos "magma/lte/cloud/go/protos"
"magma/lte/cloud/go/services/subscriberdb"
"magma/lte/cloud/go/services/subscriberdb/protos"
"magma/lte/cloud/go/services/subscriberdb/servicers"
@@ -52,6 +53,7 @@ func StartTestService(t *testing.T) {
// Add servicers
protos.RegisterSubscriberLookupServer(srv.GrpcServer, servicers.NewLookupServicer(fact, ipStore))
state_protos.RegisterIndexerServer(srv.GrpcServer, servicers.NewIndexerServicer())
+ lte_protos.RegisterSubscriberDBCloudServer(srv.GrpcServer, servicers.NewSubscriberdbServicer())
// Run service
go srv.RunTest(lis)
diff --git a/lte/gateway/c/oai/common/CMakeLists.txt b/lte/gateway/c/oai/common/CMakeLists.txt
index 9bd6534f6e4b..ff0c662e8915 100644
--- a/lte/gateway/c/oai/common/CMakeLists.txt
+++ b/lte/gateway/c/oai/common/CMakeLists.txt
@@ -9,20 +9,30 @@ include($ENV{MAGMA_ROOT}/orc8r/gateway/c/common/CMakeProtoMacros.txt)
# compile the needed protos
set(COMMON_CPP_PROTOS common_types)
set(REDIS_CPP_PROTOS redis)
+set(MCONFIG_PROTOS mconfig/mconfigs)
list(APPEND PROTO_SRCS "")
list(APPEND PROTO_HDRS "")
+create_proto_dir("orc8r" ORC8R_CPP_OUT_DIR)
set(LTE_OUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/lte/protos/oai")
generate_cpp_protos("${COMMON_CPP_PROTOS}" "${PROTO_SRCS}"
"${PROTO_HDRS}" ${STATE_PROTO_DIR} ${LTE_OUT_DIR})
create_proto_dir("orc8r" ORC8R_CPP_OUT_DIR)
+set(RPC_ORC8R_CPP_PROTOS common)
+generate_cpp_protos("${RPC_ORC8R_CPP_PROTOS}" "${PROTO_SRCS}"
+ "${PROTO_HDRS}" ${ORC8R_PROTO_DIR} ${ORC8R_CPP_OUT_DIR})
generate_cpp_protos("${REDIS_CPP_PROTOS}" "${PROTO_SRCS}"
"${PROTO_HDRS}" ${ORC8R_PROTO_DIR} ${ORC8R_CPP_OUT_DIR})
+set(MCONFIG_OUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/lte/protos")
+generate_cpp_protos("${MCONFIG_PROTOS}" "${PROTO_SRCS}"
+ "${PROTO_HDRS}" ${LTE_PROTO_DIR} ${MCONFIG_OUT_DIR})
+
message("Proto_srcs are ${PROTO_SRCS}")
include_directories(${CMAKE_CURRENT_BINARY_DIR})
include_directories(${LTE_OUT_DIR})
+include_directories(${MCONFIG_OUT_DIR})
include_directories(${ORC8R_CPP_OUT_DIR})
@@ -49,6 +59,7 @@ set(COMMON_SRC
shared_ts_log.c
log.c
state_converter.cpp
+ common_utility_funs.cpp
${PROTO_SRCS}
${PROTO_HDRS}
)
diff --git a/lte/gateway/c/oai/common/common_ies.h b/lte/gateway/c/oai/common/common_ies.h
index 66e828db1e50..79f2f812ee9e 100644
--- a/lte/gateway/c/oai/common/common_ies.h
+++ b/lte/gateway/c/oai/common/common_ies.h
@@ -36,7 +36,8 @@
#include "3gpp_23.003.h"
#define TMSI_SIZE 4
-#define MAX_IMEISV_SIZE 15
+#define MAX_IMEISV_SIZE 16
+#define MAX_IMEI_SIZE 15
#define MAX_MME_NAME_LENGTH 255
#define MAX_VLR_NAME_LENGTH 255
#define SGS_ASSOC_ACTIVE 1
diff --git a/lte/gateway/c/oai/common/common_types.h b/lte/gateway/c/oai/common/common_types.h
index 721bb413e46d..31ab40e6c0ed 100644
--- a/lte/gateway/c/oai/common/common_types.h
+++ b/lte/gateway/c/oai/common/common_types.h
@@ -97,7 +97,9 @@ typedef teid_t s1u_teid_t;
// IMSI
typedef uint64_t imsi64_t;
+typedef uint64_t imei64_t;
#define IMSI_64_FMT "%" SCNu64
+#define IMEI_64_FMT "%" SCNu64
#define IMSI_64_FMT_DYN_LEN "%.*lu"
#define INVALID_IMSI64 (imsi64_t) 0
diff --git a/lte/gateway/c/oai/common/common_utility_funs.cpp b/lte/gateway/c/oai/common/common_utility_funs.cpp
new file mode 100644
index 000000000000..f3adf07f45cd
--- /dev/null
+++ b/lte/gateway/c/oai/common/common_utility_funs.cpp
@@ -0,0 +1,60 @@
+/*
+Copyright 2020 The Magma Authors.
+
+This source code is licensed under the BSD-style license found in the
+LICENSE file in the root directory of this source tree.
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+#include
+#include
+#include "common_utility_funs.h"
+#include "lte/protos/mconfig/mconfigs.pb.h"
+
+// Extract MCC and MNC from the imsi received and match with
+// configuration
+extern "C" int match_fed_mode_map(const char* imsi, log_proto_t module) {
+ OAILOG_FUNC_IN(module);
+ imsi64_t imsi64;
+ IMSI_STRING_TO_IMSI64(imsi, &imsi64);
+ uint8_t mcc_d1 = imsi[0] - '0';
+ uint8_t mcc_d2 = imsi[1] - '0';
+ uint8_t mcc_d3 = imsi[2] - '0';
+ uint8_t mnc_d1 = imsi[3] - '0';
+ uint8_t mnc_d2 = imsi[4] - '0';
+ uint8_t mnc_d3 = imsi[5] - '0';
+ if ((mcc_d1 < 0 || mcc_d1 > 9) || (mcc_d2 < 0 || mcc_d2 > 9) ||
+ (mcc_d3 < 0 || mcc_d3 > 9) || (mnc_d1 < 0 || mnc_d1 > 9) ||
+ (mnc_d2 < 0 || mnc_d2 > 9) || (mnc_d3 < 0 || mnc_d3 > 9)) {
+ OAILOG_ERROR_UE(module, imsi64, "MCC/MNC is not a decimal digit \n");
+ OAILOG_FUNC_RETURN(module, RETURNerror);
+ }
+ for (uint8_t itr = 0; itr < mme_config.mode_map_config.num; itr++) {
+ if (((mcc_d1 == mme_config.mode_map_config.mode_map[itr].plmn.mcc_digit1) &&
+ (mcc_d2 == mme_config.mode_map_config.mode_map[itr].plmn.mcc_digit2) &&
+ (mcc_d3 == mme_config.mode_map_config.mode_map[itr].plmn.mcc_digit3) &&
+ (mnc_d1 == mme_config.mode_map_config.mode_map[itr].plmn.mnc_digit1) &&
+ (mnc_d2 ==
+ mme_config.mode_map_config.mode_map[itr].plmn.mnc_digit2))) {
+ if (mme_config.mode_map_config.mode_map[itr].plmn.mnc_digit3 != 0xf) {
+ if (mnc_d3 !=
+ mme_config.mode_map_config.mode_map[itr].plmn.mnc_digit3) {
+ continue;
+ }
+ }
+ OAILOG_FUNC_RETURN(module, mme_config.mode_map_config.mode_map[itr].mode);
+ }
+ }
+ // If the plmn is not configured set the default mode as hss + spgw_task.
+ OAILOG_INFO_UE(
+ module, imsi64,
+ "PLMN is not configured. Selecting default mode: SPGW_SUBSCRIBER \n");
+ OAILOG_FUNC_RETURN(
+ module, magma::mconfig::ModeMapItem_FederatedMode_SPGW_SUBSCRIBER);
+}
+
diff --git a/lte/gateway/c/oai/common/common_utility_funs.h b/lte/gateway/c/oai/common/common_utility_funs.h
new file mode 100644
index 000000000000..f173ba6b204c
--- /dev/null
+++ b/lte/gateway/c/oai/common/common_utility_funs.h
@@ -0,0 +1,15 @@
+#define pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "mme_config.h"
+#include "log.h"
+#include "conversions.h"
+#include "common_defs.h"
+
+int match_fed_mode_map(const char* imsi, log_proto_t module);
+#ifdef __cplusplus
+}
+#endif
diff --git a/lte/gateway/c/oai/common/conversions.h b/lte/gateway/c/oai/common/conversions.h
index 446db74c2d5b..a5bca669fc2a 100644
--- a/lte/gateway/c/oai/common/conversions.h
+++ b/lte/gateway/c/oai/common/conversions.h
@@ -42,6 +42,7 @@
#include
#include
#include
+#include
#include "common_types.h"
#include "3gpp_23.003.h"
@@ -399,6 +400,10 @@
#define IMSI_STRING_TO_IMSI64(sTRING, iMSI64_pTr) \
sscanf(sTRING, IMSI_64_FMT, iMSI64_pTr)
+/* Convert the IMEI contained by a char string NULL terminated to uint64_t */
+#define IMEI_STRING_TO_IMEI64(sTRING, iMEI64_pTr) \
+ sscanf(sTRING, IMEI_64_FMT, iMEI64_pTr)
+
#define IMSI64_TO_CSFBIMSI(iMsI64_t, cSfBiMsI_t) \
{ \
if ((iMsI64_t / 100000000000000) != 0) { \
@@ -518,6 +523,36 @@ imsi64_t imsi_to_imsi64(const imsi_t* const imsi);
} \
}
+#define IMEI_MOBID_TO_IMEI64(iMeI_t_PtR, iMEI64) \
+ { \
+ (*iMEI64) = (uint64_t)((iMeI_t_PtR)->u.num.tac1); \
+ (*iMEI64) = (10 * (*iMEI64)) + ((uint64_t)((iMeI_t_PtR)->u.num.tac2)); \
+ (*iMEI64) = (10 * (*iMEI64)) + ((uint64_t)((iMeI_t_PtR)->u.num.tac3)); \
+ (*iMEI64) = (10 * (*iMEI64)) + ((uint64_t)((iMeI_t_PtR)->u.num.tac4)); \
+ (*iMEI64) = (10 * (*iMEI64)) + ((uint64_t)((iMeI_t_PtR)->u.num.tac5)); \
+ (*iMEI64) = (10 * (*iMEI64)) + ((uint64_t)((iMeI_t_PtR)->u.num.tac6)); \
+ (*iMEI64) = (10 * (*iMEI64)) + ((uint64_t)((iMeI_t_PtR)->u.num.tac7)); \
+ (*iMEI64) = (10 * (*iMEI64)) + ((uint64_t)((iMeI_t_PtR)->u.num.tac8)); \
+ (*iMEI64) = (10 * (*iMEI64)) + ((uint64_t)((iMeI_t_PtR)->u.num.snr1)); \
+ (*iMEI64) = (10 * (*iMEI64)) + ((uint64_t)((iMeI_t_PtR)->u.num.snr2)); \
+ (*iMEI64) = (10 * (*iMEI64)) + ((uint64_t)((iMeI_t_PtR)->u.num.snr3)); \
+ (*iMEI64) = (10 * (*iMEI64)) + ((uint64_t)((iMeI_t_PtR)->u.num.snr4)); \
+ (*iMEI64) = (10 * (*iMEI64)) + ((uint64_t)((iMeI_t_PtR)->u.num.snr5)); \
+ (*iMEI64) = (10 * (*iMEI64)) + ((uint64_t)((iMeI_t_PtR)->u.num.snr6)); \
+ }
+
+#define IMEI_MOBID_TO_IMEI_TAC64(iMeI_t_PtR, tAc_PtR) \
+ { \
+ (*tAc_PtR) = (uint64_t)((iMeI_t_PtR)->u.num.tac1); \
+ (*tAc_PtR) = (10 * (*tAc_PtR)) + ((uint64_t)((iMeI_t_PtR)->u.num.tac2)); \
+ (*tAc_PtR) = (10 * (*tAc_PtR)) + ((uint64_t)((iMeI_t_PtR)->u.num.tac3)); \
+ (*tAc_PtR) = (10 * (*tAc_PtR)) + ((uint64_t)((iMeI_t_PtR)->u.num.tac4)); \
+ (*tAc_PtR) = (10 * (*tAc_PtR)) + ((uint64_t)((iMeI_t_PtR)->u.num.tac5)); \
+ (*tAc_PtR) = (10 * (*tAc_PtR)) + ((uint64_t)((iMeI_t_PtR)->u.num.tac6)); \
+ (*tAc_PtR) = (10 * (*tAc_PtR)) + ((uint64_t)((iMeI_t_PtR)->u.num.tac7)); \
+ (*tAc_PtR) = (10 * (*tAc_PtR)) + ((uint64_t)((iMeI_t_PtR)->u.num.tac8)); \
+ }
+
#define IMSI_TO_OCTET_STRING(iMsI_sTr, iMsI_len, aSN) \
do { \
int len = 0; \
diff --git a/lte/gateway/c/oai/common/redis_utils/redis_client.cpp b/lte/gateway/c/oai/common/redis_utils/redis_client.cpp
index 342be88906a3..263a051cb4d7 100644
--- a/lte/gateway/c/oai/common/redis_utils/redis_client.cpp
+++ b/lte/gateway/c/oai/common/redis_utils/redis_client.cpp
@@ -28,6 +28,7 @@ extern "C" {
#endif
#include "ServiceConfigLoader.h"
+#include // IWYU pragma: keep
using google::protobuf::Message;
@@ -84,26 +85,11 @@ std::string RedisClient::read(const std::string& key) {
return db_read_reply.as_string();
}
-int RedisClient::write_proto(const std::string& key, const Message& proto_msg) {
- std::string inner_val;
- if (serialize(proto_msg, inner_val) != RETURNok) {
- return RETURNerror;
- }
-
- // Read the existing key for current version if it exists.
- // Bump the version number of the wrapper and set its wrapped message.
+int RedisClient::write_proto_str(
+ const std::string& key, const std::string& proto_msg, uint64_t version) {
orc8r::RedisState wrapper_proto = orc8r::RedisState();
- try {
- if (key_exists(key)) {
- if (read_redis_state(key, wrapper_proto) != RETURNok) {
- return RETURNerror;
- }
- }
- } catch (const std::runtime_error& e) {
- return RETURNerror;
- }
- wrapper_proto.set_serialized_msg(inner_val);
- wrapper_proto.set_version(wrapper_proto.version() + 1);
+ wrapper_proto.set_serialized_msg(proto_msg);
+ wrapper_proto.set_version(version);
std::string str_value;
if (serialize(wrapper_proto, str_value) != RETURNok) {
diff --git a/lte/gateway/c/oai/common/redis_utils/redis_client.h b/lte/gateway/c/oai/common/redis_utils/redis_client.h
index f9d8351e7931..306e3dbd63db 100644
--- a/lte/gateway/c/oai/common/redis_utils/redis_client.h
+++ b/lte/gateway/c/oai/common/redis_utils/redis_client.h
@@ -57,10 +57,20 @@ class RedisClient {
* Writes a protobuf object to redis
* @param key
* @param proto_msg
+ * @param version
* @return response code of operation
*/
- int write_proto(
- const std::string& key, const google::protobuf::Message& proto_msg);
+ int write_proto_str(
+ const std::string& key, const std::string& proto_msg, uint64_t version);
+
+ /**
+ * Converts protobuf Message and parses it to string
+ * @param proto_msg
+ * @param str_to_serialize
+ */
+ int serialize(
+ const google::protobuf::Message& proto_msg,
+ std::string& str_to_serialize);
/**
* Reads value from redis mapped to key and returns proto object
@@ -95,14 +105,6 @@ class RedisClient {
*/
bool key_exists(const std::string& key);
- /**
- * Converts protobuf Message and parses it to string
- * @param proto_msg
- * @param str_to_serialize
- */
- int serialize(
- const google::protobuf::Message& proto_msg,
- std::string& str_to_serialize);
/**
* Takes a string and parses it to protobuf Message
* @param proto_msg
diff --git a/lte/gateway/c/oai/include/ip_forward_messages_types.h b/lte/gateway/c/oai/include/ip_forward_messages_types.h
index d15d93e6d9e9..45d2f7919508 100644
--- a/lte/gateway/c/oai/include/ip_forward_messages_types.h
+++ b/lte/gateway/c/oai/include/ip_forward_messages_types.h
@@ -80,8 +80,6 @@ typedef struct {
typedef struct {
teid_t context_teid; ///< Tunnel Endpoint Identifier S11
- SGIStatus_t status; ///< Status of endpoint creation (Failed = 0xFF or
- ///< Success = 0x0)
uint8_t num_bearers_modified;
bearer_cxt_t bearer_contexts_to_be_modified[BEARERS_PER_UE];
uint8_t num_bearers_removed;
diff --git a/lte/gateway/c/oai/include/mme_app_ue_context.h b/lte/gateway/c/oai/include/mme_app_ue_context.h
index 51a002b48541..2c611059725e 100644
--- a/lte/gateway/c/oai/include/mme_app_ue_context.h
+++ b/lte/gateway/c/oai/include/mme_app_ue_context.h
@@ -239,6 +239,7 @@ typedef struct pdn_context_s {
protocol_configuration_options_t* pco;
bool ue_rej_act_def_ber_req;
+ bool route_s11_messages_to_s8_task;
} pdn_context_t;
typedef enum {
diff --git a/lte/gateway/c/oai/include/mme_config.h b/lte/gateway/c/oai/include/mme_config.h
index a4b87aba2c0e..dee94a8bd46a 100644
--- a/lte/gateway/c/oai/include/mme_config.h
+++ b/lte/gateway/c/oai/include/mme_config.h
@@ -47,6 +47,7 @@
#include "3gpp_24.008.h"
#include "log.h"
#include "service303.h"
+#include "hashtable.h"
/* Currently supporting max 5 GUMMEI's in the mme configuration */
#define MIN_GUMMEI 1
@@ -58,8 +59,12 @@
#define CIDR_SPLIT_LIST_COUNT 2
#define MAX_APN_CORRECTION_MAP_LIST 10
#define MAX_RESTRICTED_PLMN 10
+#define MAX_LEN_TAC 8
+#define MAX_LEN_SNR 6
+#define MAX_LEN_IMEI 15
#define MAX_FED_MODE_MAP_CONFIG 10
#define MAX_IMSI_LENGTH 15
+#define MAX_IMEI_HTBL_SZ 32
#define MME_CONFIG_STRING_MME_CONFIG "MME"
#define MME_CONFIG_STRING_PID_DIRECTORY "PID_DIRECTORY"
@@ -118,6 +123,9 @@
#define MME_CONFIG_STRING_TAC "TAC"
#define MME_CONFIG_STRING_RESTRICTED_PLMN_LIST "RESTRICTED_PLMN_LIST"
+#define MME_CONFIG_STRING_BLOCKED_IMEI_LIST "BLOCKED_IMEI_LIST"
+#define MME_CONFIG_STRING_IMEI_TAC "IMEI_TAC"
+#define MME_CONFIG_STRING_SNR "SNR"
#define MME_CONFIG_STRING_NETWORK_INTERFACES_CONFIG "NETWORK_INTERFACES"
#define MME_CONFIG_STRING_INTERFACE_NAME_FOR_S1_MME \
@@ -310,6 +318,12 @@ typedef struct restricted_plmn_s {
plmn_t plmn[MAX_RESTRICTED_PLMN];
} restricted_plmn_config_t;
+typedef struct blocked_imei_list_s {
+ int num;
+ // data is NULL
+ hash_table_uint64_ts_t* imei_htbl;
+} blocked_imei_list_t;
+
typedef struct fed_mode_map_s {
uint8_t mode;
plmn_t plmn;
@@ -355,6 +369,8 @@ typedef struct mme_config_s {
restricted_plmn_config_t restricted_plmn;
+ blocked_imei_list_t blocked_imei;
+
served_tai_t served_tai;
service303_data_t service303_config;
diff --git a/lte/gateway/c/oai/include/s8_messages_def.h b/lte/gateway/c/oai/include/s8_messages_def.h
index 790ca40cedd7..26082c5cb398 100644
--- a/lte/gateway/c/oai/include/s8_messages_def.h
+++ b/lte/gateway/c/oai/include/s8_messages_def.h
@@ -15,3 +15,5 @@ limitations under the License.
// instead.
MESSAGE_DEF(
S8_CREATE_SESSION_RSP, s8_create_session_response_t, s8_create_session_rsp)
+MESSAGE_DEF(
+ S8_DELETE_SESSION_RSP, s8_delete_session_response_t, s8_delete_session_rsp)
diff --git a/lte/gateway/c/oai/include/s8_messages_types.h b/lte/gateway/c/oai/include/s8_messages_types.h
index 04aa3906b11a..2f1281cd55c6 100644
--- a/lte/gateway/c/oai/include/s8_messages_types.h
+++ b/lte/gateway/c/oai/include/s8_messages_types.h
@@ -17,6 +17,7 @@ limitations under the License.
#include "common_types.h"
#define S8_CREATE_SESSION_RSP(mSGpTR) (mSGpTR)->ittiMsg.s8_create_session_rsp
+#define S8_DELETE_SESSION_RSP(mSGpTR) (mSGpTR)->ittiMsg.s8_delete_session_rsp
typedef struct s8_bearer_context_s {
ebi_t eps_bearer_id;
@@ -33,8 +34,12 @@ typedef struct s8_create_session_response_s {
teid_t context_teid; // SGW_S11_teid, created per PDN
ebi_t eps_bearer_id;
s8_bearer_context_t bearer_context[BEARERS_PER_UE];
- uint8_t response_cause;
uint8_t apn_restriction_value;
fteid_t pgw_s8_cp_teid;
uint32_t cause;
} s8_create_session_response_t;
+
+typedef struct s8_delete_session_response_s {
+ teid_t context_teid; // SGW_S11_teid, created per PDN
+ uint32_t cause;
+} s8_delete_session_response_t;
diff --git a/lte/gateway/c/oai/include/sgw_context_manager.h b/lte/gateway/c/oai/include/sgw_context_manager.h
index 969a2cf3dcaf..c7680e8cf184 100644
--- a/lte/gateway/c/oai/include/sgw_context_manager.h
+++ b/lte/gateway/c/oai/include/sgw_context_manager.h
@@ -38,6 +38,7 @@ void sgw_display_sgw_eps_bearer_context(
const sgw_eps_bearer_ctxt_t* eps_bearer_ctxt);
void sgw_display_s11teid2mme(mme_sgw_tunnel_t* mme_sgw_tunnel);
void sgw_display_s11_bearer_context_information(
+ log_proto_t module,
sgw_eps_bearer_context_information_t* sgw_context_information);
void pgw_lite_cm_free_apn(pgw_apn_t** apnP);
diff --git a/lte/gateway/c/oai/include/state_manager.h b/lte/gateway/c/oai/include/state_manager.h
index 2afe949a1d31..2e62389fbc52 100644
--- a/lte/gateway/c/oai/include/state_manager.h
+++ b/lte/gateway/c/oai/include/state_manager.h
@@ -130,15 +130,22 @@ class StateManager {
if (persist_state_enabled) {
ProtoType state_proto = ProtoType();
StateConverter::state_to_proto(state_cache_p, &state_proto);
-
- if (redis_client->write_proto(table_key, state_proto) != RETURNok) {
- OAILOG_ERROR(log_task, "Failed to write state to db");
- return;
+ std::string proto_str;
+ redis_client->serialize(state_proto, proto_str);
+ std::size_t new_hash = std::hash{}(proto_str);
+
+ if (new_hash != this->task_state_hash) {
+ if (redis_client->write_proto_str(
+ table_key, proto_str, this->task_state_version) != RETURNok) {
+ OAILOG_ERROR(log_task, "Failed to write state to db");
+ return;
+ }
+ OAILOG_DEBUG(log_task, "Finished writing state");
+ this->task_state_version++;
+ this->state_dirty = false;
+ this->task_state_hash = new_hash;
}
- OAILOG_DEBUG(log_task, "Finished writing state");
}
-
- this->state_dirty = false;
}
virtual void write_ue_state_to_db(
@@ -147,17 +154,27 @@ class StateManager {
is_initialized,
"StateManager init() function should be called to initialize state");
+ std::string proto_str;
ProtoUe ue_proto = ProtoUe();
StateConverter::ue_to_proto(ue_context, &ue_proto);
- std::string key = IMSI_PREFIX + imsi_str + ":" + task_name;
- if (redis_client->write_proto(key, ue_proto) != RETURNok) {
- OAILOG_ERROR(
- log_task, "Failed to write UE state to db for IMSI %s",
- imsi_str.c_str());
- return;
+ redis_client->serialize(ue_proto, proto_str);
+ std::size_t new_hash = std::hash{}(proto_str);
+
+ if (new_hash != this->ue_state_hash) {
+ std::string key = IMSI_PREFIX + imsi_str + ":" + task_name;
+ if (redis_client->write_proto_str(key, proto_str, ue_state_version) !=
+ RETURNok) {
+ OAILOG_ERROR(
+ log_task, "Failed to write UE state to db for IMSI %s",
+ imsi_str.c_str());
+ return;
+ }
+
+ this->ue_state_version++;
+ this->ue_state_hash = new_hash;
+ OAILOG_DEBUG(
+ log_task, "Finished writing UE state for IMSI %s", imsi_str.c_str());
}
- OAILOG_DEBUG(
- log_task, "Finished writing UE state for IMSI %s", imsi_str.c_str());
}
std::string get_imsi_str(imsi64_t imsi64) {
@@ -201,6 +218,10 @@ class StateManager {
is_initialized(false),
state_dirty(false),
persist_state_enabled(false),
+ task_state_hash(0),
+ ue_state_hash(0),
+ task_state_version(0),
+ ue_state_version(0),
log_task(LOG_UTIL) {}
virtual ~StateManager() = default;
@@ -225,10 +246,15 @@ class StateManager {
// Flag for check asserting if the state has been initialized.
bool is_initialized;
// Flag for check asserting that write should be done after read.
- // TODO: Convert this to state versioning variable
bool state_dirty;
// Flag for enabling writing and reading to db.
bool persist_state_enabled;
+ // State version counters for task and ue context
+ uint64_t task_state_version;
+ uint64_t ue_state_version;
+ // Last written hash values for task and ue context
+ std::size_t task_state_hash;
+ std::size_t ue_state_hash;
protected:
std::string table_key;
diff --git a/lte/gateway/c/oai/lib/hashtable/hashtable.h b/lte/gateway/c/oai/lib/hashtable/hashtable.h
index 5a6542542d31..c4d43eedb1fd 100644
--- a/lte/gateway/c/oai/lib/hashtable/hashtable.h
+++ b/lte/gateway/c/oai/lib/hashtable/hashtable.h
@@ -55,6 +55,7 @@ typedef enum hashtable_return_code_e {
HASH_TABLE_KEY_NOT_EXISTS,
HASH_TABLE_SEARCH_NO_RESULT,
HASH_TABLE_KEY_ALREADY_EXISTS,
+ HASH_TABLE_SAME_KEY_VALUE_EXISTS,
HASH_TABLE_BAD_PARAMETER_HASHTABLE,
HASH_TABLE_BAD_PARAMETER_KEY,
HASH_TABLE_SYSTEM_ERROR,
diff --git a/lte/gateway/c/oai/lib/hashtable/hashtable_uint64.c b/lte/gateway/c/oai/lib/hashtable/hashtable_uint64.c
index 7fa032ede1ec..b7260047304d 100644
--- a/lte/gateway/c/oai/lib/hashtable/hashtable_uint64.c
+++ b/lte/gateway/c/oai/lib/hashtable/hashtable_uint64.c
@@ -680,12 +680,11 @@ hashtable_rc_t hashtable_uint64_ts_insert(
__FUNCTION__, bdata(hashtblP->name), keyP, dataP);
return HASH_TABLE_INSERT_OVERWRITTEN_DATA;
}
- node->data = dataP;
pthread_mutex_unlock(&hashtblP->lock_nodes[hash]);
PRINT_HASHTABLE(
hashtblP, "%s(%s,key 0x%" PRIx64 " data %" PRIx64 ") return OK\n",
__FUNCTION__, bdata(hashtblP->name), keyP, dataP);
- return HASH_TABLE_OK;
+ return HASH_TABLE_SAME_KEY_VALUE_EXISTS;
}
node = node->next;
diff --git a/lte/gateway/c/oai/lib/mobility_client/MobilityClientAPI.cpp b/lte/gateway/c/oai/lib/mobility_client/MobilityClientAPI.cpp
index dc1483f624cb..75d8d85708be 100644
--- a/lte/gateway/c/oai/lib/mobility_client/MobilityClientAPI.cpp
+++ b/lte/gateway/c/oai/lib/mobility_client/MobilityClientAPI.cpp
@@ -28,6 +28,7 @@
#include "spgw_types.h"
#include "intertask_interface.h"
#include "common_types.h"
+#include "log.h"
#include "MobilityServiceClient.h"
diff --git a/lte/gateway/c/oai/lib/openflow/controller/ControllerEvents.cpp b/lte/gateway/c/oai/lib/openflow/controller/ControllerEvents.cpp
index 50e12df9f74c..759b2584b247 100644
--- a/lte/gateway/c/oai/lib/openflow/controller/ControllerEvents.cpp
+++ b/lte/gateway/c/oai/lib/openflow/controller/ControllerEvents.cpp
@@ -144,6 +144,8 @@ AddGTPTunnelEvent::AddGTPTunnelEvent(
pgw_ip_(INADDR_ZERO),
in_tei_(in_tei),
out_tei_(out_tei),
+ pgw_in_tei_(0),
+ pgw_out_tei_(0),
imsi_(imsi),
dl_flow_valid_(false),
dl_flow_(),
@@ -162,6 +164,8 @@ AddGTPTunnelEvent::AddGTPTunnelEvent(
pgw_ip_(INADDR_ZERO),
in_tei_(in_tei),
out_tei_(out_tei),
+ pgw_in_tei_(0),
+ pgw_out_tei_(0),
imsi_(imsi),
dl_flow_valid_(true),
dl_flow_(*dl_flow),
@@ -173,7 +177,8 @@ AddGTPTunnelEvent::AddGTPTunnelEvent(
AddGTPTunnelEvent::AddGTPTunnelEvent(
const struct in_addr ue_ip, struct in6_addr* ue_ipv6, int vlan,
const struct in_addr enb_ip, const struct in_addr pgw_ip,
- const uint32_t in_tei, const uint32_t out_tei, const char* imsi,
+ const uint32_t in_tei, const uint32_t out_tei, const uint32_t pgw_in_tei,
+ const uint32_t pgw_out_tei, const char* imsi,
const struct ip_flow_dl* dl_flow, const uint32_t dl_flow_precedence,
uint32_t enb_gtp_port, uint32_t pgw_gtp_port)
: ue_info_(ue_ip, ue_ipv6, vlan),
@@ -181,6 +186,8 @@ AddGTPTunnelEvent::AddGTPTunnelEvent(
pgw_ip_(pgw_ip),
in_tei_(in_tei),
out_tei_(out_tei),
+ pgw_in_tei_(pgw_in_tei),
+ pgw_out_tei_(pgw_out_tei),
imsi_(imsi),
dl_flow_valid_(false),
dl_flow_(),
@@ -192,13 +199,16 @@ AddGTPTunnelEvent::AddGTPTunnelEvent(
AddGTPTunnelEvent::AddGTPTunnelEvent(
const struct in_addr ue_ip, struct in6_addr* ue_ipv6, int vlan,
const struct in_addr enb_ip, const struct in_addr pgw_ip,
- const uint32_t in_tei, const uint32_t out_tei, const char* imsi,
- uint32_t enb_gtp_port, uint32_t pgw_gtp_port)
+ const uint32_t in_tei, const uint32_t out_tei, const uint32_t pgw_in_tei,
+ const uint32_t pgw_out_tei, const char* imsi, uint32_t enb_gtp_port,
+ uint32_t pgw_gtp_port)
: ue_info_(ue_ip, vlan),
enb_ip_(enb_ip),
pgw_ip_(pgw_ip),
in_tei_(in_tei),
out_tei_(out_tei),
+ pgw_in_tei_(pgw_in_tei),
+ pgw_out_tei_(pgw_out_tei),
imsi_(imsi),
dl_flow_valid_(false),
dl_flow_(),
@@ -231,6 +241,14 @@ const uint32_t AddGTPTunnelEvent::get_out_tei() const {
return out_tei_;
}
+const uint32_t AddGTPTunnelEvent::get_pgw_in_tei() const {
+ return pgw_in_tei_;
+}
+
+const uint32_t AddGTPTunnelEvent::get_pgw_out_tei() const {
+ return pgw_out_tei_;
+}
+
const std::string& AddGTPTunnelEvent::get_imsi() const {
return imsi_;
}
diff --git a/lte/gateway/c/oai/lib/openflow/controller/ControllerEvents.h b/lte/gateway/c/oai/lib/openflow/controller/ControllerEvents.h
index 8bee0b9b49da..23909cf41615 100644
--- a/lte/gateway/c/oai/lib/openflow/controller/ControllerEvents.h
+++ b/lte/gateway/c/oai/lib/openflow/controller/ControllerEvents.h
@@ -187,15 +187,17 @@ class AddGTPTunnelEvent : public ExternalEvent {
AddGTPTunnelEvent(
const struct in_addr ue_ip, struct in6_addr* ue_ipv6, int vlan,
const struct in_addr enb_ip, const struct in_addr pgw_ip,
- const uint32_t in_tei, const uint32_t out_tei, const char* imsi,
+ const uint32_t in_tei, const uint32_t out_tei, const uint32_t pgw_in_tei,
+ const uint32_t pgw_out_tei, const char* imsi,
const struct ip_flow_dl* dl_flow, const uint32_t dl_flow_precedence,
uint32_t enb_gtp_port, uint32_t pgw_gtp_port);
AddGTPTunnelEvent(
const struct in_addr ue_ip, struct in6_addr* ue_ipv6, int vlan,
const struct in_addr enb_ip, const struct in_addr pgw_ip,
- const uint32_t in_tei, const uint32_t out_tei, const char* imsi,
- uint32_t enb_gtp_port, uint32_t pgw_gtp_port);
+ const uint32_t in_tei, const uint32_t out_tei, const uint32_t pgw_in_tei,
+ const uint32_t pgw_out_tei, const char* imsi, uint32_t enb_gtp_port,
+ uint32_t pgw_gtp_port);
const struct UeNetworkInfo& get_ue_info() const;
const struct in_addr& get_ue_ip() const;
@@ -206,6 +208,9 @@ class AddGTPTunnelEvent : public ExternalEvent {
const uint32_t get_in_tei() const;
const uint32_t get_out_tei() const;
+ const uint32_t get_pgw_in_tei() const;
+ const uint32_t get_pgw_out_tei() const;
+
const std::string& get_imsi() const;
const bool is_dl_flow_valid() const;
const struct ip_flow_dl& get_dl_flow() const;
@@ -219,6 +224,8 @@ class AddGTPTunnelEvent : public ExternalEvent {
const struct in_addr pgw_ip_;
const uint32_t in_tei_;
const uint32_t out_tei_;
+ const uint32_t pgw_in_tei_;
+ const uint32_t pgw_out_tei_;
const std::string imsi_;
const struct ip_flow_dl dl_flow_;
const bool dl_flow_valid_;
diff --git a/lte/gateway/c/oai/lib/openflow/controller/ControllerMain.cpp b/lte/gateway/c/oai/lib/openflow/controller/ControllerMain.cpp
index bf501ef8d4fd..81204a87fddb 100644
--- a/lte/gateway/c/oai/lib/openflow/controller/ControllerMain.cpp
+++ b/lte/gateway/c/oai/lib/openflow/controller/ControllerMain.cpp
@@ -126,18 +126,18 @@ int openflow_controller_del_gtp_tunnel(
int openflow_controller_add_gtp_s8_tunnel(
struct in_addr ue, struct in6_addr* ue_ipv6, int vlan, struct in_addr enb,
- struct in_addr pgw, uint32_t i_tei, uint32_t o_tei, const char* imsi,
- struct ip_flow_dl* flow_dl, uint32_t flow_precedence_dl,
- uint32_t enb_gtp_port, uint32_t pgw_gtp_port) {
+ struct in_addr pgw, uint32_t i_tei, uint32_t o_tei, uint32_t pgw_i_tei,
+ uint32_t pgw_o_tei, const char* imsi, struct ip_flow_dl* flow_dl,
+ uint32_t flow_precedence_dl, uint32_t enb_gtp_port, uint32_t pgw_gtp_port) {
if (flow_dl) {
auto add_tunnel = std::make_shared(
- ue, ue_ipv6, vlan, enb, pgw, i_tei, o_tei, imsi, flow_dl,
- flow_precedence_dl, enb_gtp_port, pgw_gtp_port);
+ ue, ue_ipv6, vlan, enb, pgw, i_tei, o_tei, pgw_i_tei, pgw_o_tei, imsi,
+ flow_dl, flow_precedence_dl, enb_gtp_port, pgw_gtp_port);
ctrl.inject_external_event(add_tunnel, external_event_callback);
} else {
auto add_tunnel = std::make_shared(
- ue, ue_ipv6, vlan, enb, pgw, i_tei, o_tei, imsi, enb_gtp_port,
- pgw_gtp_port);
+ ue, ue_ipv6, vlan, enb, pgw, i_tei, o_tei, pgw_i_tei, pgw_o_tei, imsi,
+ enb_gtp_port, pgw_gtp_port);
ctrl.inject_external_event(add_tunnel, external_event_callback);
}
OAILOG_FUNC_RETURN(LOG_GTPV1U, RETURNok);
diff --git a/lte/gateway/c/oai/lib/openflow/controller/ControllerMain.h b/lte/gateway/c/oai/lib/openflow/controller/ControllerMain.h
index c859f31d558d..9d30252d87e3 100644
--- a/lte/gateway/c/oai/lib/openflow/controller/ControllerMain.h
+++ b/lte/gateway/c/oai/lib/openflow/controller/ControllerMain.h
@@ -56,9 +56,9 @@ int openflow_controller_delete_paging_rule(struct in_addr ue_ip);
int openflow_controller_add_gtp_s8_tunnel(
struct in_addr ue, struct in6_addr* ue_ipv6, int vlan, struct in_addr enb,
- struct in_addr pgw, uint32_t i_tei, uint32_t o_tei, const char* imsi,
- struct ip_flow_dl* flow_dl, uint32_t flow_precedence_dl,
- uint32_t enb_gtp_port, uint32_t pgw_gtp_port);
+ struct in_addr pgw, uint32_t i_tei, uint32_t o_tei, uint32_t pgw_i_tei,
+ uint32_t pgw_o_tei, const char* imsi, struct ip_flow_dl* flow_dl,
+ uint32_t flow_precedence_dl, uint32_t enb_gtp_port, uint32_t pgw_gtp_port);
int openflow_controller_del_gtp_s8_tunnel(
struct in_addr ue, struct in6_addr* ue_ipv6, uint32_t i_tei,
diff --git a/lte/gateway/c/oai/lib/openflow/controller/GTPApplication.cpp b/lte/gateway/c/oai/lib/openflow/controller/GTPApplication.cpp
index 494d72d67a0f..4b1c64243600 100644
--- a/lte/gateway/c/oai/lib/openflow/controller/GTPApplication.cpp
+++ b/lte/gateway/c/oai/lib/openflow/controller/GTPApplication.cpp
@@ -49,12 +49,12 @@ GTPApplication::GTPApplication(
void GTPApplication::event_callback(
const ControllerEvent& ev, const OpenflowMessenger& messenger) {
if (ev.get_type() == EVENT_ADD_GTP_TUNNEL) {
- printf("pbs: reg add tun");
auto add_tunnel_event = static_cast(ev);
add_uplink_tunnel_flow(add_tunnel_event, messenger);
add_downlink_tunnel_flow(
- add_tunnel_event, messenger, uplink_port_num_, false);
- add_downlink_tunnel_flow(add_tunnel_event, messenger, mtr_port_num_, false);
+ add_tunnel_event, messenger, uplink_port_num_, false, false);
+ add_downlink_tunnel_flow(
+ add_tunnel_event, messenger, mtr_port_num_, false, false);
add_downlink_arp_flow(add_tunnel_event, messenger, uplink_port_num_);
add_downlink_arp_flow(add_tunnel_event, messenger, mtr_port_num_);
} else if (ev.get_type() == EVENT_DELETE_GTP_TUNNEL) {
@@ -65,16 +65,22 @@ void GTPApplication::event_callback(
delete_downlink_arp_flow(del_tunnel_event, messenger, uplink_port_num_);
delete_downlink_arp_flow(del_tunnel_event, messenger, mtr_port_num_);
} else if (ev.get_type() == EVENT_ADD_GTP_S8_TUNNEL) {
- printf("pbs: S8 add tun");
auto add_tunnel_event = static_cast(ev);
+ auto imsi = IMSIEncoder::compact_imsi(add_tunnel_event.get_imsi());
+
+ OAILOG_DEBUG_UE(LOG_GTPV1U, imsi, "s8: add: TEID: s1-in %u s1-out %u s8-in %u s8-out %u\n",
+ add_tunnel_event.get_in_tei(), add_tunnel_event.get_out_tei(),
+ add_tunnel_event.get_pgw_in_tei(), add_tunnel_event.get_pgw_out_tei());
+
add_uplink_s8_tunnel_flow(add_tunnel_event, messenger);
int pgw_port = add_tunnel_event.get_pgw_gtp_portno();
if (pgw_port == 0) {
pgw_port = GTPApplication::gtp0_port_num_;
}
- add_downlink_tunnel_flow(add_tunnel_event, messenger, pgw_port, true);
- add_downlink_tunnel_flow(add_tunnel_event, messenger, mtr_port_num_, true);
+ add_downlink_tunnel_flow(add_tunnel_event, messenger, pgw_port, true, true);
+ add_downlink_tunnel_flow(
+ add_tunnel_event, messenger, mtr_port_num_, true, true);
add_downlink_arp_flow(add_tunnel_event, messenger, mtr_port_num_);
} else if (ev.get_type() == EVENT_DELETE_GTP_S8_TUNNEL) {
auto del_tunnel_event = static_cast(ev);
@@ -207,7 +213,7 @@ void GTPApplication::add_uplink_s8_tunnel_flow(
add_tunnel_match(uplink_fm, ev.get_enb_gtp_portno(), ev.get_in_tei());
add_tunnel_flow_action(
- ev.get_out_tei(), ev.get_in_tei(), ev.get_imsi(), ev.get_pgw_ip(),
+ ev.get_pgw_out_tei(), ev.get_in_tei(), ev.get_imsi(), ev.get_pgw_ip(),
ev.get_pgw_gtp_portno(), ev.get_connection(), messenger, uplink_fm,
"S8 Uplink", true);
}
@@ -412,28 +418,36 @@ void GTPApplication::add_tunnel_flow_action(
void GTPApplication::add_downlink_tunnel_flow_action(
const AddGTPTunnelEvent& ev, const OpenflowMessenger& messenger,
- of13::FlowMod downlink_fm, bool passthrough) {
+ of13::FlowMod downlink_fm, bool passthrough, bool from_pgw) {
+ uint32_t in_teid;
+ if (from_pgw) {
+ in_teid = ev.get_pgw_in_tei();
+ } else {
+ in_teid = ev.get_in_tei();
+ }
+
add_tunnel_flow_action(
- ev.get_out_tei(), ev.get_in_tei(), ev.get_imsi(), ev.get_enb_ip(),
+ ev.get_out_tei(), in_teid, ev.get_imsi(), ev.get_enb_ip(),
ev.get_enb_gtp_portno(), ev.get_connection(), messenger, downlink_fm,
"S1 Downlink", passthrough);
}
void GTPApplication::add_downlink_tunnel_flow_ipv4(
const AddGTPTunnelEvent& ev, const OpenflowMessenger& messenger,
- uint32_t ingress_port, bool passthrough) {
+ uint32_t ingress_port, bool passthrough, bool from_pgw) {
uint32_t flow_priority =
convert_precedence_to_priority(ev.get_dl_flow_precedence());
of13::FlowMod downlink_fm =
messenger.create_default_flow_mod(0, of13::OFPFC_ADD, flow_priority);
add_downlink_match(downlink_fm, ev.get_ue_ip(), ingress_port);
- add_downlink_tunnel_flow_action(ev, messenger, downlink_fm, passthrough);
+ add_downlink_tunnel_flow_action(
+ ev, messenger, downlink_fm, passthrough, from_pgw);
}
void GTPApplication::add_downlink_tunnel_flow_ipv6(
const AddGTPTunnelEvent& ev, const OpenflowMessenger& messenger,
- uint32_t ingress_port, bool passthrough) {
+ uint32_t ingress_port, bool passthrough, bool from_pgw) {
uint32_t flow_priority =
convert_precedence_to_priority(ev.get_dl_flow_precedence());
of13::FlowMod downlink_fm =
@@ -441,35 +455,40 @@ void GTPApplication::add_downlink_tunnel_flow_ipv6(
add_downlink_match_ipv6(
downlink_fm, ev.get_ue_info().get_ipv6(), ingress_port);
- add_downlink_tunnel_flow_action(ev, messenger, downlink_fm, passthrough);
+ add_downlink_tunnel_flow_action(
+ ev, messenger, downlink_fm, passthrough, from_pgw);
}
void GTPApplication::add_downlink_tunnel_flow_ded_brr(
const AddGTPTunnelEvent& ev, const OpenflowMessenger& messenger,
- uint32_t ingress_port, bool passthrough) {
+ uint32_t ingress_port, bool passthrough, bool from_pgw) {
uint32_t flow_priority =
convert_precedence_to_priority(ev.get_dl_flow_precedence());
of13::FlowMod downlink_fm =
messenger.create_default_flow_mod(0, of13::OFPFC_ADD, flow_priority);
add_ded_brr_dl_match(downlink_fm, ev.get_dl_flow(), ingress_port);
- add_downlink_tunnel_flow_action(ev, messenger, downlink_fm, passthrough);
+ add_downlink_tunnel_flow_action(
+ ev, messenger, downlink_fm, passthrough, from_pgw);
}
void GTPApplication::add_downlink_tunnel_flow(
const AddGTPTunnelEvent& ev, const OpenflowMessenger& messenger,
- uint32_t ingress_port, bool passthrough) {
+ uint32_t ingress_port, bool passthrough, bool from_pgw) {
if (ev.is_dl_flow_valid()) {
- add_downlink_tunnel_flow_ded_brr(ev, messenger, ingress_port, passthrough);
+ add_downlink_tunnel_flow_ded_brr(
+ ev, messenger, ingress_port, passthrough, from_pgw);
return;
}
UeNetworkInfo ue_info = ev.get_ue_info();
if (ue_info.is_ue_ipv4_addr_valid()) {
- add_downlink_tunnel_flow_ipv4(ev, messenger, ingress_port, passthrough);
+ add_downlink_tunnel_flow_ipv4(
+ ev, messenger, ingress_port, passthrough, from_pgw);
}
if (ue_info.is_ue_ipv6_addr_valid()) {
- add_downlink_tunnel_flow_ipv6(ev, messenger, ingress_port, passthrough);
+ add_downlink_tunnel_flow_ipv6(
+ ev, messenger, ingress_port, passthrough, from_pgw);
}
}
diff --git a/lte/gateway/c/oai/lib/openflow/controller/GTPApplication.h b/lte/gateway/c/oai/lib/openflow/controller/GTPApplication.h
index 69d7592605bb..a8e82a569573 100644
--- a/lte/gateway/c/oai/lib/openflow/controller/GTPApplication.h
+++ b/lte/gateway/c/oai/lib/openflow/controller/GTPApplication.h
@@ -63,7 +63,7 @@ class GTPApplication : public Application {
*/
void add_downlink_tunnel_flow(
const AddGTPTunnelEvent& ev, const OpenflowMessenger& messenger,
- uint32_t port_number, bool passthrough);
+ uint32_t port_number, bool passthrough, bool from_pgw);
/*
* Add downlink tunnel flow for S8
@@ -181,17 +181,17 @@ class GTPApplication : public Application {
void add_downlink_tunnel_flow_action(
const AddGTPTunnelEvent& ev, const OpenflowMessenger& messenger,
- of13::FlowMod downlink_fm, bool passthrough);
+ of13::FlowMod downlink_fm, bool passthrough, bool from_pgw);
void add_downlink_tunnel_flow_ipv4(
const AddGTPTunnelEvent& ev, const OpenflowMessenger& messenger,
- uint32_t port_number, bool passthrough);
+ uint32_t port_number, bool passthrough, bool from_pgw);
void add_downlink_tunnel_flow_ipv6(
const AddGTPTunnelEvent& ev, const OpenflowMessenger& messenger,
- uint32_t port_number, bool passthrough);
+ uint32_t port_number, bool passthrough, bool from_pgw);
void add_downlink_tunnel_flow_ded_brr(
const AddGTPTunnelEvent& ev, const OpenflowMessenger& messenger,
- uint32_t port_number, bool passthrough);
+ uint32_t port_number, bool passthrough, bool from_pgw);
void delete_downlink_tunnel_flow_ipv4(
const DeleteGTPTunnelEvent& ev, const OpenflowMessenger& messenger,
diff --git a/lte/gateway/c/oai/lib/pcef/pcef_handlers.cpp b/lte/gateway/c/oai/lib/pcef/pcef_handlers.cpp
index 3bc9b0a9182f..c9cbcae591e6 100644
--- a/lte/gateway/c/oai/lib/pcef/pcef_handlers.cpp
+++ b/lte/gateway/c/oai/lib/pcef/pcef_handlers.cpp
@@ -313,7 +313,7 @@ int get_msisdn_from_session_req(
return len;
}
-static int get_imeisv_from_session_req(
+int get_imeisv_from_session_req(
const itti_s11_create_session_request_t* saved_req, char* imeisv) {
if (saved_req->mei.present & MEI_IMEISV) {
// IMEISV as defined in 3GPP TS 23.003 MEI_IMEISV
diff --git a/lte/gateway/c/oai/lib/pcef/pcef_handlers.h b/lte/gateway/c/oai/lib/pcef/pcef_handlers.h
index 48c769601309..af7783ad255a 100644
--- a/lte/gateway/c/oai/lib/pcef/pcef_handlers.h
+++ b/lte/gateway/c/oai/lib/pcef/pcef_handlers.h
@@ -98,6 +98,8 @@ int get_msisdn_from_session_req(
char convert_digit_to_char(char digit);
+int get_imeisv_from_session_req(
+ const itti_s11_create_session_request_t* saved_req, char* imeisv);
#ifdef __cplusplus
}
#endif
diff --git a/lte/gateway/c/oai/lib/s6a_proxy/S6aClient.cpp b/lte/gateway/c/oai/lib/s6a_proxy/S6aClient.cpp
index 01b2154b68fa..0f9801568f0f 100644
--- a/lte/gateway/c/oai/lib/s6a_proxy/S6aClient.cpp
+++ b/lte/gateway/c/oai/lib/s6a_proxy/S6aClient.cpp
@@ -27,6 +27,10 @@
#include "feg/protos/s6a_proxy.pb.h"
#include "mme_config.h"
#include "common_defs.h"
+#include "common_utility_funs.h"
+extern "C" {
+#include "log.h"
+}
namespace grpc {
class Status;
@@ -99,45 +103,6 @@ S6aClient& S6aClient::get_subdb_instance() {
static S6aClient subdb_instance(false);
return subdb_instance;
}
-
-// Extract MCC and MNC from the imsi received and match with
-// configuration
-int match_fed_mode_map(const char* imsi) {
- uint8_t mcc_d1 = imsi[0] - '0';
- uint8_t mcc_d2 = imsi[1] - '0';
- uint8_t mcc_d3 = imsi[2] - '0';
- uint8_t mnc_d1 = imsi[3] - '0';
- uint8_t mnc_d2 = imsi[4] - '0';
- uint8_t mnc_d3 = imsi[5] - '0';
- if ((mcc_d1 < 0 || mcc_d1 > 9) || (mcc_d2 < 0 || mcc_d2 > 9) ||
- (mcc_d3 < 0 || mcc_d3 > 9) || (mnc_d1 < 0 || mnc_d1 > 9) ||
- (mnc_d2 < 0 || mnc_d2 > 9) || (mnc_d3 < 0 || mnc_d3 > 9)) {
- std::cout << "[ERROR] MCC/MNC is not a decimal digit " << std::endl;
- return -1;
- }
- for (uint8_t itr = 0; itr < mme_config.mode_map_config.num; itr++) {
- if (((mcc_d1 == mme_config.mode_map_config.mode_map[itr].plmn.mcc_digit1) &&
- (mcc_d2 == mme_config.mode_map_config.mode_map[itr].plmn.mcc_digit2) &&
- (mcc_d3 == mme_config.mode_map_config.mode_map[itr].plmn.mcc_digit3) &&
- (mnc_d1 == mme_config.mode_map_config.mode_map[itr].plmn.mnc_digit1) &&
- (mnc_d2 ==
- mme_config.mode_map_config.mode_map[itr].plmn.mnc_digit2))) {
- if (mme_config.mode_map_config.mode_map[itr].plmn.mnc_digit3 != 0xf) {
- if (mnc_d3 !=
- mme_config.mode_map_config.mode_map[itr].plmn.mnc_digit3) {
- continue;
- }
- }
- return mme_config.mode_map_config.mode_map[itr].mode;
- }
- }
- // If the plmn is not found/configured we still create a channel
- // towards the FeG as the default mode is HSS + spgw_task.
- std::cout << "[INFO] PLMN is not found/configured. Selecting default mode"
- << std::endl;
- return (magma::mconfig::ModeMapItem_FederatedMode_SPGW_SUBSCRIBER);
-}
-
S6aClient::S6aClient(bool enable_s6a_proxy_channel) {
// Create channel based on relay_enabled, enable_s6a_proxy_channel and
// cloud_subscriberdb_enabled flags.
@@ -165,7 +130,7 @@ S6aClient::S6aClient(bool enable_s6a_proxy_channel) {
void S6aClient::purge_ue(
const char* imsi, std::function callbk) {
S6aClient* client_tmp;
- int fed_mode = match_fed_mode_map(imsi);
+ int fed_mode = match_fed_mode_map(imsi, LOG_S6A);
if ((fed_mode == magma::mconfig::ModeMapItem_FederatedMode_SPGW_SUBSCRIBER) ||
(fed_mode == magma::mconfig::ModeMapItem_FederatedMode_S8_SUBSCRIBER)) {
client_tmp = &get_s6a_proxy_instance();
@@ -201,7 +166,7 @@ void S6aClient::authentication_info_req(
const s6a_auth_info_req_t* const msg,
std::function callbk) {
S6aClient* client_tmp;
- int fed_mode = match_fed_mode_map(msg->imsi);
+ int fed_mode = match_fed_mode_map(msg->imsi, LOG_S6A);
if ((fed_mode == magma::mconfig::ModeMapItem_FederatedMode_SPGW_SUBSCRIBER) ||
(fed_mode == magma::mconfig::ModeMapItem_FederatedMode_S8_SUBSCRIBER)) {
client_tmp = &get_s6a_proxy_instance();
@@ -237,7 +202,7 @@ void S6aClient::update_location_request(
const s6a_update_location_req_t* const msg,
std::function callbk) {
S6aClient* client_tmp;
- int fed_mode = match_fed_mode_map(msg->imsi);
+ int fed_mode = match_fed_mode_map(msg->imsi, LOG_S6A);
if ((fed_mode == magma::mconfig::ModeMapItem_FederatedMode_SPGW_SUBSCRIBER) ||
(fed_mode == magma::mconfig::ModeMapItem_FederatedMode_S8_SUBSCRIBER)) {
client_tmp = &get_s6a_proxy_instance();
diff --git a/lte/gateway/c/oai/lib/s8_proxy/S8Client.cpp b/lte/gateway/c/oai/lib/s8_proxy/S8Client.cpp
index be649a823592..ec507d024ac7 100644
--- a/lte/gateway/c/oai/lib/s8_proxy/S8Client.cpp
+++ b/lte/gateway/c/oai/lib/s8_proxy/S8Client.cpp
@@ -60,4 +60,23 @@ void S8Client::s8_create_session_request(
response->set_response_reader(std::move(response_reader));
}
+void S8Client::s8_delete_session_request(
+ const DeleteSessionRequestPgw& dsr_req,
+ std::function callback) {
+ S8Client& client = get_instance();
+ // Create a raw response pointer that stores a callback to be called when the
+ // gRPC call is answered
+ auto response = new AsyncLocalResponse(
+ std::move(callback), RESPONSE_TIMEOUT);
+ // Create a response reader for the `DeleteSession` RPC call. This reader
+ // stores the client context, the request to pass in, and the queue to add
+ // the response to when done
+ auto response_reader = client.stub_->AsyncDeleteSession(
+ response->get_context(), dsr_req, &client.queue_);
+ // Set the reader for the local response. This executes the `DeleteSession`
+ // response using the response reader. When it is done, the callback stored in
+ // `local_response` will be called
+ response->set_response_reader(std::move(response_reader));
+}
+
} // namespace magma
diff --git a/lte/gateway/c/oai/lib/s8_proxy/S8Client.h b/lte/gateway/c/oai/lib/s8_proxy/S8Client.h
index 0df1fcca8a83..64c91a4206cc 100644
--- a/lte/gateway/c/oai/lib/s8_proxy/S8Client.h
+++ b/lte/gateway/c/oai/lib/s8_proxy/S8Client.h
@@ -47,6 +47,11 @@ class S8Client : public GRPCReceiver {
const CreateSessionRequestPgw& csr_req,
std::function callback);
+ // Send Delete Session Request
+ static void s8_delete_session_request(
+ const DeleteSessionRequestPgw& dsr_req,
+ std::function callback);
+
public:
S8Client(S8Client const&) = delete;
void operator=(S8Client const&) = delete;
diff --git a/lte/gateway/c/oai/lib/s8_proxy/s8_client_api.cpp b/lte/gateway/c/oai/lib/s8_proxy/s8_client_api.cpp
index 3d64ea391e37..47a30b50b57e 100644
--- a/lte/gateway/c/oai/lib/s8_proxy/s8_client_api.cpp
+++ b/lte/gateway/c/oai/lib/s8_proxy/s8_client_api.cpp
@@ -28,7 +28,7 @@ extern task_zmq_ctx_t grpc_service_task_zmq_ctx;
static void convert_proto_msg_to_itti_csr(
magma::feg::CreateSessionResponsePgw& response,
- s8_create_session_response_t* s5_response);
+ s8_create_session_response_t* s5_response, bearer_qos_t dflt_bearer_qos);
static void get_qos_from_proto_msg(
const magma::feg::QosInformation& proto_qos, bearer_qos_t* bearer_qos) {
@@ -49,14 +49,16 @@ static void get_fteid_from_proto_msg(
OAILOG_FUNC_IN(LOG_SGW_S8);
pgw_fteid->teid = proto_fteid.teid();
if (proto_fteid.ipv4_address().c_str()) {
- struct in_addr addr = {0};
- memcpy(&addr, proto_fteid.ipv4_address().c_str(), sizeof(in_addr));
- pgw_fteid->ipv4_address = addr;
+ pgw_fteid->ipv4 = true;
+ inet_pton(
+ AF_INET, proto_fteid.ipv4_address().c_str(),
+ &(pgw_fteid->ipv4_address));
}
if (proto_fteid.ipv6_address().c_str()) {
- struct in6_addr ip6_addr;
- memcpy(&ip6_addr, proto_fteid.ipv6_address().c_str(), sizeof(in6_addr));
- pgw_fteid->ipv6_address = ip6_addr;
+ pgw_fteid->ipv6 = true;
+ inet_pton(
+ AF_INET6, proto_fteid.ipv6_address().c_str(),
+ &(pgw_fteid->ipv6_address));
}
OAILOG_FUNC_OUT(LOG_SGW_S8);
}
@@ -69,22 +71,22 @@ static void get_paa_from_proto_msg(
case magma::feg::PDNType::IPV4: {
paa->pdn_type = IPv4;
auto ip = proto_paa.ipv4_address();
- memcpy(&paa->ipv4_address, ip.c_str(), sizeof(ip.c_str()));
+ inet_pton(AF_INET, ip.c_str(), &(paa->ipv4_address));
break;
}
case magma::feg::PDNType::IPV6: {
paa->pdn_type = IPv6;
auto ip = proto_paa.ipv6_address();
- memcpy(&paa->ipv6_address, ip.c_str(), sizeof(ip.c_str()));
+ inet_pton(AF_INET6, ip.c_str(), &(paa->ipv6_address));
paa->ipv6_prefix_length = IPV6_PREFIX_LEN;
break;
}
case magma::feg::PDNType::IPV4V6: {
paa->pdn_type = IPv4_AND_v6;
auto ip = proto_paa.ipv4_address();
- memcpy(&paa->ipv4_address, ip.c_str(), sizeof(ip.c_str()));
+ inet_pton(AF_INET, ip.c_str(), &(paa->ipv4_address));
auto ipv6 = proto_paa.ipv6_address();
- memcpy(&paa->ipv6_address, ipv6.c_str(), sizeof(ipv6.c_str()));
+ inet_pton(AF_INET6, ipv6.c_str(), &(paa->ipv6_address));
paa->ipv6_prefix_length = IPV6_PREFIX_LEN;
break;
}
@@ -101,8 +103,59 @@ static void get_paa_from_proto_msg(
OAILOG_FUNC_OUT(LOG_SGW_S8);
}
-static void recv_s8_create_session_response(
+static void recv_s8_delete_session_response(
imsi64_t imsi64, teid_t context_teid, const grpc::Status& status,
+ magma::feg::DeleteSessionResponsePgw& response) {
+ OAILOG_FUNC_IN(LOG_SGW_S8);
+
+ s8_delete_session_response_t* s8_delete_session_rsp = NULL;
+ MessageDef* message_p = NULL;
+ message_p = itti_alloc_new_message(TASK_GRPC_SERVICE, S8_DELETE_SESSION_RSP);
+ if (!message_p) {
+ OAILOG_ERROR_UE(
+ LOG_SGW_S8, imsi64,
+ "Failed to allocate memory for S8_DELETE_SESSION_RSP for "
+ "context_teid" TEID_FMT "\n",
+ context_teid);
+ OAILOG_FUNC_OUT(LOG_SGW_S8);
+ }
+ s8_delete_session_rsp = &message_p->ittiMsg.s8_delete_session_rsp;
+ message_p->ittiMsgHeader.imsi = imsi64;
+ s8_delete_session_rsp->context_teid = context_teid;
+
+ if (status.ok()) {
+ if (response.has_gtp_error()) {
+ s8_delete_session_rsp->cause = response.mutable_gtp_error()->cause();
+ } else {
+ s8_delete_session_rsp->cause = REQUEST_ACCEPTED;
+ }
+ } else {
+ OAILOG_ERROR_UE(
+ LOG_SGW_S8, imsi64,
+ "Received gRPC error for delete session response for "
+ "context_teid " TEID_FMT "\n",
+ context_teid);
+ s8_delete_session_rsp->cause = REMOTE_PEER_NOT_RESPONDING;
+ }
+ OAILOG_INFO_UE(
+ LOG_UTIL, imsi64,
+ "Sending delete session response to sgw_s8 task for "
+ "context_teid " TEID_FMT "\n",
+ context_teid);
+ if ((send_msg_to_task(&grpc_service_task_zmq_ctx, TASK_SGW_S8, message_p)) !=
+ RETURNok) {
+ OAILOG_ERROR_UE(
+ LOG_SGW_S8, imsi64,
+ "Failed to send delete session response to sgw_s8 task for"
+ "context_teid " TEID_FMT "\n",
+ context_teid);
+ }
+ OAILOG_FUNC_OUT(LOG_SGW_S8);
+}
+
+static void recv_s8_create_session_response(
+ imsi64_t imsi64, teid_t context_teid, bearer_qos_t dflt_bearer_qos,
+ const grpc::Status& status,
magma::feg::CreateSessionResponsePgw& response) {
OAILOG_FUNC_IN(LOG_SGW_S8);
s8_create_session_response_t* s5_response = NULL;
@@ -120,7 +173,7 @@ static void recv_s8_create_session_response(
message_p->ittiMsgHeader.imsi = imsi64;
s5_response->context_teid = context_teid;
if (status.ok()) {
- convert_proto_msg_to_itti_csr(response, s5_response);
+ convert_proto_msg_to_itti_csr(response, s5_response, dflt_bearer_qos);
} else {
OAILOG_ERROR(
LOG_SGW_S8,
@@ -150,8 +203,8 @@ static void convert_uli_to_proto_msg(
uli->set_sac(msg_uli.s.sai.sac);
uli->set_rac(msg_uli.s.rai.rac);
uli->set_tac(msg_uli.s.tai.tac);
- uli->set_eci(msg_uli.s.ecgi.cell_identity.cell_id);
- uli->set_menbi(msg_uli.s.ecgi.cell_identity.enb_id);
+ uli->set_eci(msg_uli.s.ecgi.cell_identity.enb_id);
+ uli->set_menbi(0);
OAILOG_FUNC_OUT(LOG_SGW_S8);
}
@@ -281,6 +334,17 @@ static void get_msisdn_from_csr_req(
OAILOG_FUNC_OUT(LOG_SGW_S8);
}
+static void convert_imeisv_to_string(char* imeisv) {
+ OAILOG_FUNC_IN(LOG_SGW_S8);
+ uint8_t idx = 0;
+ for (; idx < IMEISV_DIGITS_MAX; idx++) {
+ imeisv[idx] = convert_digit_to_char(imeisv[idx]);
+ }
+ imeisv[idx] = '\0';
+
+ OAILOG_FUNC_OUT(LOG_SGW_S8);
+}
+
static void fill_s8_create_session_req(
const itti_s11_create_session_request_t* msg,
magma::feg::CreateSessionRequestPgw* csr, teid_t sgw_s8_teid) {
@@ -305,7 +369,10 @@ static void fill_s8_create_session_req(
mnc[2] = '\0';
mnc_len = 2;
}
-
+ char imeisv[IMEISV_DIGITS_MAX + 1];
+ get_imeisv_from_session_req(msg, imeisv);
+ convert_imeisv_to_string(imeisv);
+ csr->set_mei(imeisv, IMEISV_DIGITS_MAX);
magma::feg::ServingNetwork* serving_network = csr->mutable_serving_network();
serving_network->set_mcc(mcc, 3);
serving_network->set_mnc(mnc, mnc_len);
@@ -320,6 +387,9 @@ static void fill_s8_create_session_req(
magma::feg::BearerContext* bc = csr->mutable_bearer_context();
convert_bearer_context_to_proto(
&msg->bearer_contexts_to_be_created.bearer_contexts[0], bc);
+ // set the mbr within bearer qos same as apn-ambr
+ bc->mutable_qos()->mutable_mbr()->set_br_ul(msg->ambr.br_ul);
+ bc->mutable_qos()->mutable_mbr()->set_br_dl(msg->ambr.br_dl);
}
csr->set_c_agw_teid(sgw_s8_teid);
csr->set_charging_characteristics(
@@ -336,6 +406,7 @@ void send_s8_create_session_request(
imsi64_t imsi64) {
OAILOG_FUNC_IN(LOG_SGW_S8);
magma::feg::CreateSessionRequestPgw csr_req;
+ bearer_qos_t dflt_bearer_qos = {0};
// teid shall remain same for both sgw's s11 interface and s8 interface as
// teid is allocated per PDN
@@ -345,18 +416,21 @@ void send_s8_create_session_request(
sgw_s11_teid);
fill_s8_create_session_req(msg, &csr_req, sgw_s11_teid);
+ dflt_bearer_qos =
+ msg->bearer_contexts_to_be_created.bearer_contexts[0].bearer_level_qos;
magma::S8Client::s8_create_session_request(
csr_req,
- [imsi64, sgw_s11_teid](
+ [imsi64, sgw_s11_teid, dflt_bearer_qos](
grpc::Status status, magma::feg::CreateSessionResponsePgw response) {
- recv_s8_create_session_response(imsi64, sgw_s11_teid, status, response);
+ recv_s8_create_session_response(
+ imsi64, sgw_s11_teid, dflt_bearer_qos, status, response);
});
}
static void convert_proto_msg_to_itti_csr(
magma::feg::CreateSessionResponsePgw& response,
- s8_create_session_response_t* s5_response) {
+ s8_create_session_response_t* s5_response, bearer_qos_t dflt_bearer_qos) {
OAILOG_FUNC_IN(LOG_SGW_S8);
s5_response->apn_restriction_value = response.apn_restriction();
get_fteid_from_proto_msg(
@@ -368,9 +442,44 @@ static void convert_proto_msg_to_itti_csr(
s8_bc->eps_bearer_id = response.bearer_context().id();
s5_response->eps_bearer_id = s8_bc->eps_bearer_id;
s8_bc->charging_id = response.bearer_context().charging_id();
- get_qos_from_proto_msg(response.bearer_context().qos(), &s8_bc->qos);
+ if (response.bearer_context().valid_qos()) {
+ get_qos_from_proto_msg(response.bearer_context().qos(), &s8_bc->qos);
+ } else {
+ // If qos is not received from PGW, set the qos that was sent in CS Req
+ s8_bc->qos = dflt_bearer_qos;
+ }
get_fteid_from_proto_msg(
response.bearer_context().user_plane_fteid(), &s8_bc->pgw_s8_up);
- s5_response->cause = response.mutable_gtp_error()->cause();
+ if (response.has_gtp_error()) {
+ s5_response->cause = response.mutable_gtp_error()->cause();
+ } else {
+ s5_response->cause = REQUEST_ACCEPTED;
+ }
+ OAILOG_FUNC_OUT(LOG_SGW_S8);
+}
+
+void send_s8_delete_session_request(
+ imsi64_t imsi64, Imsi_t imsi, teid_t sgw_s11_teid, teid_t pgw_s5_teid,
+ ebi_t bearer_id) {
+ OAILOG_FUNC_IN(LOG_SGW_S8);
+ OAILOG_INFO_UE(
+ LOG_SGW_S8, imsi64,
+ "Sending delete session request for context_teid:" TEID_FMT "\n",
+ sgw_s11_teid);
+
+ magma::feg::DeleteSessionRequestPgw dsr_req;
+
+ dsr_req.Clear();
+ dsr_req.set_imsi((char*) imsi.digit, imsi.length);
+ dsr_req.set_bearer_id(bearer_id);
+ dsr_req.mutable_c_pgw_fteid()->set_teid(pgw_s5_teid);
+ dsr_req.set_c_agw_teid(sgw_s11_teid);
+ magma::S8Client::s8_delete_session_request(
+ dsr_req,
+ [imsi64, sgw_s11_teid](
+ grpc::Status status, magma::feg::DeleteSessionResponsePgw response) {
+ recv_s8_delete_session_response(imsi64, sgw_s11_teid, status, response);
+ });
+
OAILOG_FUNC_OUT(LOG_SGW_S8);
}
diff --git a/lte/gateway/c/oai/lib/s8_proxy/s8_client_api.h b/lte/gateway/c/oai/lib/s8_proxy/s8_client_api.h
index 6bd66272e2f2..ac23e8e4c6d1 100644
--- a/lte/gateway/c/oai/lib/s8_proxy/s8_client_api.h
+++ b/lte/gateway/c/oai/lib/s8_proxy/s8_client_api.h
@@ -17,9 +17,13 @@ extern "C" {
#endif
#include "intertask_interface.h"
#include "common_types.h"
+
void send_s8_create_session_request(
teid_t sgw_s11_teid, const itti_s11_create_session_request_t* msg,
imsi64_t imsi64);
+void send_s8_delete_session_request(
+ imsi64_t imsi64, Imsi_t imsi, teid_t sgw_s11_teid, teid_t pgw_s5_teid,
+ ebi_t bearer_id);
#ifdef __cplusplus
}
#endif
diff --git a/lte/gateway/c/oai/tasks/gtpv1-u/gtp_tunnel_openflow.c b/lte/gateway/c/oai/tasks/gtpv1-u/gtp_tunnel_openflow.c
index 0f6d6e9f27d5..118914a02a75 100644
--- a/lte/gateway/c/oai/tasks/gtpv1-u/gtp_tunnel_openflow.c
+++ b/lte/gateway/c/oai/tasks/gtpv1-u/gtp_tunnel_openflow.c
@@ -270,14 +270,16 @@ int openflow_del_tunnel(
/* S8 tunnel related APIs */
int openflow_add_s8_tunnel(
struct in_addr ue, struct in6_addr* ue_ipv6, int vlan, struct in_addr enb,
- struct in_addr pgw, uint32_t i_tei, uint32_t o_tei, Imsi_t imsi,
- struct ip_flow_dl* flow_dl, uint32_t flow_precedence_dl) {
+ struct in_addr pgw, uint32_t i_tei, uint32_t o_tei, uint32_t pgw_i_tei,
+ uint32_t pgw_o_tei, Imsi_t imsi, struct ip_flow_dl* flow_dl,
+ uint32_t flow_precedence_dl) {
uint32_t enb_portno = find_gtp_port_no(enb);
uint32_t pgw_portno = find_gtp_port_no(pgw);
return openflow_controller_add_gtp_s8_tunnel(
- ue, ue_ipv6, vlan, enb, pgw, i_tei, o_tei, (const char*) imsi.digit,
- flow_dl, flow_precedence_dl, enb_portno, pgw_portno);
+ ue, ue_ipv6, vlan, enb, pgw, i_tei, o_tei, pgw_i_tei, pgw_o_tei,
+ (const char*) imsi.digit, flow_dl, flow_precedence_dl, enb_portno,
+ pgw_portno);
}
int openflow_del_s8_tunnel(
diff --git a/lte/gateway/c/oai/tasks/gtpv1-u/gtpv1u.h b/lte/gateway/c/oai/tasks/gtpv1-u/gtpv1u.h
index ca01b53b0d6d..459265fdee23 100644
--- a/lte/gateway/c/oai/tasks/gtpv1-u/gtpv1u.h
+++ b/lte/gateway/c/oai/tasks/gtpv1-u/gtpv1u.h
@@ -145,8 +145,9 @@ struct gtp_tunnel_ops {
uint32_t i_tei, uint32_t o_tei, struct ip_flow_dl* flow_dl);
int (*add_s8_tunnel)(
struct in_addr ue, struct in6_addr* ue_ipv6, int vlan, struct in_addr enb,
- struct in_addr pgw, uint32_t i_tei, uint32_t o_tei, Imsi_t imsi,
- struct ip_flow_dl* flow_dl, uint32_t flow_precedence_dl);
+ struct in_addr pgw, uint32_t i_tei, uint32_t o_tei, uint32_t pgw_i_tei,
+ uint32_t pgw_o_tei, Imsi_t imsi, struct ip_flow_dl* flow_dl,
+ uint32_t flow_precedence_dl);
int (*del_s8_tunnel)(
struct in_addr enb, struct in_addr pgw, struct in_addr ue,
struct in6_addr* ue_ipv6, uint32_t i_tei, uint32_t o_tei,
@@ -176,6 +177,7 @@ int gtpv1u_add_tunnel(
int gtpv1u_add_s8_tunnel(
struct in_addr ue, struct in6_addr* ue_ipv6, int vlan, struct in_addr enb,
- struct in_addr pgw, uint32_t i_tei, uint32_t o_tei, Imsi_t imsi,
- struct ip_flow_dl* flow_dl, uint32_t flow_precedence_dl);
+ struct in_addr pgw, uint32_t i_tei, uint32_t o_tei, uint32_t pgw_i_tei,
+ uint32_t pgw_o_tei, Imsi_t imsi, struct ip_flow_dl* flow_dl,
+ uint32_t flow_precedence_dl);
#endif /* FILE_GTPV1_U_SEEN */
diff --git a/lte/gateway/c/oai/tasks/gtpv1-u/gtpv1u_task.c b/lte/gateway/c/oai/tasks/gtpv1-u/gtpv1u_task.c
index f492af7be8cf..dd3a99e284eb 100644
--- a/lte/gateway/c/oai/tasks/gtpv1-u/gtpv1u_task.c
+++ b/lte/gateway/c/oai/tasks/gtpv1-u/gtpv1u_task.c
@@ -202,13 +202,14 @@ int gtpv1u_add_tunnel(
int gtpv1u_add_s8_tunnel(
struct in_addr ue, struct in6_addr* ue_ipv6, int vlan, struct in_addr enb,
- struct in_addr pgw, uint32_t i_tei, uint32_t o_tei, Imsi_t imsi,
- struct ip_flow_dl* flow_dl, uint32_t flow_precedence_dl) {
+ struct in_addr pgw, uint32_t i_tei, uint32_t o_tei, uint32_t pgw_i_tei,
+ uint32_t pgw_o_tei, Imsi_t imsi, struct ip_flow_dl* flow_dl,
+ uint32_t flow_precedence_dl) {
OAILOG_DEBUG(LOG_GTPV1U, "Add S8 tunnel ue %s", inet_ntoa(ue));
if (gtp_tunnel_ops->add_s8_tunnel) {
return gtp_tunnel_ops->add_s8_tunnel(
- ue, ue_ipv6, vlan, enb, pgw, i_tei, o_tei, imsi, flow_dl,
- flow_precedence_dl);
+ ue, ue_ipv6, vlan, enb, pgw, i_tei, o_tei, pgw_i_tei, pgw_o_tei, imsi,
+ flow_dl, flow_precedence_dl);
} else {
return -EINVAL;
}
diff --git a/lte/gateway/c/oai/tasks/mme_app/mme_app_bearer.c b/lte/gateway/c/oai/tasks/mme_app/mme_app_bearer.c
index 98555be400d2..0c17df0845cc 100644
--- a/lte/gateway/c/oai/tasks/mme_app/mme_app_bearer.c
+++ b/lte/gateway/c/oai/tasks/mme_app/mme_app_bearer.c
@@ -84,6 +84,10 @@
extern task_zmq_ctx_t mme_app_task_zmq_ctx;
extern int pdn_connectivity_delete(emm_context_t* emm_context, pdn_cid_t pid);
+static void send_s11_modify_bearer_request(
+ ue_mm_context_t* ue_context_p, pdn_context_t* pdn_context_p,
+ MessageDef* message_p);
+
int send_modify_bearer_req(mme_ue_s1ap_id_t ue_id, ebi_t ebi) {
OAILOG_FUNC_IN(LOG_MME_APP);
@@ -187,11 +191,7 @@ int send_modify_bearer_req(mme_ue_s1ap_id_t ue_id, ebi_t ebi) {
message_p->ittiMsgHeader.imsi = ue_context_p->emm_context._imsi64;
- OAILOG_INFO_UE(
- LOG_MME_APP, ue_context_p->emm_context._imsi64,
- "Sending S11_MODIFY_BEARER_REQUEST to SGW for ue" MME_UE_S1AP_ID_FMT "\n",
- ue_id);
- send_msg_to_task(&mme_app_task_zmq_ctx, TASK_SPGW, message_p);
+ send_s11_modify_bearer_request(ue_context_p, pdn_context_p, message_p);
OAILOG_FUNC_RETURN(LOG_MME_APP, RETURNok);
}
@@ -1527,7 +1527,9 @@ static int mme_app_send_modify_bearer_request_for_active_pdns(
mme_app_build_modify_bearer_request_message(
ue_context_p, initial_ctxt_setup_rsp_p, s11_modify_bearer_request, &pid,
&bc_to_be_removed_idx);
- send_msg_to_task(&mme_app_task_zmq_ctx, TASK_SPGW, message_p);
+
+ send_s11_modify_bearer_request(
+ ue_context_p, ue_context_p->pdn_contexts[pid], message_p);
} // end of for loop
OAILOG_FUNC_RETURN(LOG_MME_APP, RETURNok);
@@ -3431,11 +3433,9 @@ void mme_app_handle_path_switch_request(
message_p->ittiMsgHeader.imsi = ue_context_p->emm_context._imsi64;
- OAILOG_DEBUG_UE(
- LOG_MME_APP, ue_context_p->emm_context._imsi64,
- "MME_APP send S11_MODIFY_BEARER_REQUEST to teid %u \n",
- s11_modify_bearer_request->teid);
- send_msg_to_task(&mme_app_task_zmq_ctx, TASK_SPGW, message_p);
+ if (pdn_context) {
+ send_s11_modify_bearer_request(ue_context_p, pdn_context, message_p);
+ }
ue_context_p->path_switch_req = true;
OAILOG_FUNC_OUT(LOG_MME_APP);
@@ -3941,12 +3941,9 @@ void mme_app_handle_e_rab_modification_ind(
s11_modify_bearer_request->trxn = NULL;
message_p->ittiMsgHeader.imsi = ue_context_p->emm_context._imsi64;
-
- OAILOG_DEBUG_UE(
- LOG_MME_APP, ue_context_p->emm_context._imsi64,
- "MME_APP send S11_MODIFY_BEARER_REQUEST to teid %u \n",
- s11_modify_bearer_request->teid);
- send_msg_to_task(&mme_app_task_zmq_ctx, TASK_SPGW, message_p);
+ if (pdn_context) {
+ send_s11_modify_bearer_request(ue_context_p, pdn_context, message_p);
+ }
OAILOG_FUNC_OUT(LOG_MME_APP);
}
//------------------------------------------------------------------------------
@@ -4086,3 +4083,30 @@ void mme_app_handle_modify_bearer_rsp(
}
OAILOG_FUNC_OUT(LOG_MME_APP);
}
+
+void send_s11_modify_bearer_request(
+ ue_mm_context_t* ue_context_p, pdn_context_t* pdn_context_p,
+ MessageDef* message_p) {
+ OAILOG_FUNC_IN(LOG_MME_APP);
+ Imsi_t imsi = {0};
+ IMSI64_TO_STRING(
+ ue_context_p->emm_context._imsi64, (char*) (&imsi.digit),
+ ue_context_p->emm_context._imsi.length);
+
+ if (pdn_context_p->route_s11_messages_to_s8_task) {
+ OAILOG_INFO_UE(
+ LOG_MME_APP, ue_context_p->emm_context._imsi64,
+ "Sending S11 modify bearer req message to SGW_s8 task for "
+ "ue_id " MME_UE_S1AP_ID_FMT "\n",
+ ue_context_p->mme_ue_s1ap_id);
+ send_msg_to_task(&mme_app_task_zmq_ctx, TASK_SGW_S8, message_p);
+ } else {
+ OAILOG_INFO_UE(
+ LOG_MME_APP, ue_context_p->emm_context._imsi64,
+ "Sending S11 modify bearer req message to SPGW task for "
+ "ue_id " MME_UE_S1AP_ID_FMT "\n",
+ ue_context_p->mme_ue_s1ap_id);
+ send_msg_to_task(&mme_app_task_zmq_ctx, TASK_SPGW, message_p);
+ }
+ OAILOG_FUNC_OUT(LOG_MME_APP);
+}
diff --git a/lte/gateway/c/oai/tasks/mme_app/mme_app_detach.c b/lte/gateway/c/oai/tasks/mme_app/mme_app_detach.c
index 5a0ce522fc8e..7c53714b7571 100644
--- a/lte/gateway/c/oai/tasks/mme_app/mme_app_detach.c
+++ b/lte/gateway/c/oai/tasks/mme_app/mme_app_detach.c
@@ -32,6 +32,7 @@
#include
#include "log.h"
+#include "conversions.h"
#include "intertask_interface.h"
#include "gcc_diag.h"
#include "mme_config.h"
@@ -115,10 +116,25 @@ void mme_app_send_delete_session_request(
message_p->ittiMsgHeader.imsi = ue_context_p->emm_context._imsi64;
- send_msg_to_task(&mme_app_task_zmq_ctx, TASK_SPGW, message_p);
- OAILOG_INFO(
- LOG_MME_APP, "Send Delete session Req for teid " TEID_FMT "\n",
- ue_context_p->mme_teid_s11);
+ Imsi_t imsi = {0};
+ IMSI64_TO_STRING(
+ ue_context_p->emm_context._imsi64, (char*) (&imsi.digit),
+ ue_context_p->emm_context._imsi.length);
+
+ if (ue_context_p->pdn_contexts[cid]->route_s11_messages_to_s8_task) {
+ OAILOG_INFO_UE(
+ LOG_MME_APP, ue_context_p->emm_context._imsi64,
+ "Send delete session Req for teid to sgw_s8 task " TEID_FMT "\n",
+ ue_context_p->mme_teid_s11);
+ send_msg_to_task(&mme_app_task_zmq_ctx, TASK_SGW_S8, message_p);
+ } else {
+ OAILOG_INFO_UE(
+ LOG_MME_APP, ue_context_p->emm_context._imsi64,
+ "Send delete session Req for teid to spgw task " TEID_FMT "\n",
+ ue_context_p->mme_teid_s11);
+ send_msg_to_task(&mme_app_task_zmq_ctx, TASK_SPGW, message_p);
+ }
+
increment_counter("mme_spgw_delete_session_req", 1, NO_LABELS);
OAILOG_FUNC_OUT(LOG_MME_APP);
}
diff --git a/lte/gateway/c/oai/tasks/mme_app/mme_app_itti_messaging.c b/lte/gateway/c/oai/tasks/mme_app/mme_app_itti_messaging.c
index f199cca7154a..615c2dcb7a66 100644
--- a/lte/gateway/c/oai/tasks/mme_app/mme_app_itti_messaging.c
+++ b/lte/gateway/c/oai/tasks/mme_app/mme_app_itti_messaging.c
@@ -48,6 +48,7 @@
#include "esm_data.h"
#include "mme_app_desc.h"
#include "s11_messages_types.h"
+#include "common_utility_funs.h"
#if EMBEDDED_SGW
#define TASK_SPGW TASK_SPGW_APP
@@ -236,7 +237,8 @@ int mme_app_send_s11_create_session_req(
} else {
session_request_p->msisdn.length = 0;
}
-
+ session_request_p->mei.present = MEI_IMEISV;
+ session_request_p->mei.choice.imeisv = ue_mm_context->emm_context._imeisv;
// Fill User Location Information
session_request_p->uli.present = 0; // initialize the presencemask
mme_app_get_user_location_information(&session_request_p->uli, ue_mm_context);
@@ -373,20 +375,23 @@ int mme_app_send_s11_create_session_req(
session_request_p->serving_network.mnc[2] =
ue_mm_context->e_utran_cgi.plmn.mnc_digit3;
session_request_p->selection_mode = MS_O_N_P_APN_S_V;
-
- OAILOG_INFO_UE(
- LOG_MME_APP, ue_mm_context->emm_context._imsi64,
- "Sending S11 CREATE SESSION REQ message to SPGW for "
- "ue_id " MME_UE_S1AP_ID_FMT "\n",
- ue_mm_context->mme_ue_s1ap_id);
- if ((send_msg_to_task(&mme_app_task_zmq_ctx, TASK_SPGW, message_p)) !=
- RETURNok) {
- OAILOG_ERROR_UE(
+ int mode =
+ match_fed_mode_map((char*) session_request_p->imsi.digit, LOG_MME_APP);
+ if (mode == S8_SUBSCRIBER) {
+ OAILOG_INFO_UE(
LOG_MME_APP, ue_mm_context->emm_context._imsi64,
- "Failed to send S11 CREATE SESSION REQ message to SPGW for "
+ "Sending s11 create session req message to SGW_s8 task for "
"ue_id " MME_UE_S1AP_ID_FMT "\n",
ue_mm_context->mme_ue_s1ap_id);
- OAILOG_FUNC_RETURN(LOG_MME_APP, RETURNerror);
+ send_msg_to_task(&mme_app_task_zmq_ctx, TASK_SGW_S8, message_p);
+ ue_mm_context->pdn_contexts[pdn_cid]->route_s11_messages_to_s8_task = true;
+ } else {
+ OAILOG_INFO_UE(
+ LOG_MME_APP, ue_mm_context->emm_context._imsi64,
+ "Sending s11 create session req message to SPGW task for "
+ "ue_id " MME_UE_S1AP_ID_FMT "\n",
+ ue_mm_context->mme_ue_s1ap_id);
+ send_msg_to_task(&mme_app_task_zmq_ctx, TASK_SPGW, message_p);
}
OAILOG_FUNC_RETURN(LOG_MME_APP, RETURNok);
}
diff --git a/lte/gateway/c/oai/tasks/mme_app/mme_app_itti_messaging.h b/lte/gateway/c/oai/tasks/mme_app/mme_app_itti_messaging.h
index 377507743a0a..4f27d0dfbb53 100644
--- a/lte/gateway/c/oai/tasks/mme_app/mme_app_itti_messaging.h
+++ b/lte/gateway/c/oai/tasks/mme_app/mme_app_itti_messaging.h
@@ -131,5 +131,4 @@ void mme_app_itti_sgsap_tmsi_reallocation_comp(
void mme_app_itti_sgsap_ue_activity_ind(
const char* imsi, const unsigned int imsi_len);
-
#endif /* FILE_MME_APP_ITTI_MESSAGING_SEEN */
diff --git a/lte/gateway/c/oai/tasks/mme_app/mme_app_location.c b/lte/gateway/c/oai/tasks/mme_app/mme_app_location.c
index 2e994986cc92..827fd91faa08 100644
--- a/lte/gateway/c/oai/tasks/mme_app/mme_app_location.c
+++ b/lte/gateway/c/oai/tasks/mme_app/mme_app_location.c
@@ -258,10 +258,19 @@ int mme_app_handle_s6a_update_location_ans(
}
}
- // Stop ULR Response timer if running
+ // Stop ULR Response timer.
+ // If expired its timer id should be MME_APP_TIMER_INACTIVE_ID and
+ // it should be already treated as failure
if (ue_mm_context->ulr_response_timer.id != MME_APP_TIMER_INACTIVE_ID) {
mme_app_stop_timer(ue_mm_context->ulr_response_timer.id);
ue_mm_context->ulr_response_timer.id = MME_APP_TIMER_INACTIVE_ID;
+ } else {
+ OAILOG_ERROR(
+ LOG_MME_APP,
+ "ULR Response Timer has invalid id. This implies that the timer has "
+ "expired and ULR has been handled as failure. \n ",
+ ue_mm_context->mme_ue_s1ap_id);
+ OAILOG_FUNC_RETURN(LOG_MME_APP, RETURNerror);
}
ue_mm_context->subscription_known = SUBSCRIPTION_KNOWN;
diff --git a/lte/gateway/c/oai/tasks/mme_app/mme_app_pdn_context.c b/lte/gateway/c/oai/tasks/mme_app/mme_app_pdn_context.c
index df4ca9ddd80b..bfa328a78854 100644
--- a/lte/gateway/c/oai/tasks/mme_app/mme_app_pdn_context.c
+++ b/lte/gateway/c/oai/tasks/mme_app/mme_app_pdn_context.c
@@ -93,7 +93,9 @@ pdn_context_t* mme_app_create_pdn_context(
&pdn_context->default_bearer_eps_subscribed_qos_profile,
&apn_configuration->subscribed_qos,
sizeof(eps_subscribed_qos_profile_t));
- // pdn_context->subscribed_apn_ambr = ;
+ memcpy(
+ &pdn_context->subscribed_apn_ambr, &apn_configuration->ambr,
+ sizeof(ambr_t));
// pdn_context->pgw_apn_ambr = ;
pdn_context->is_active = true;
pdn_context->apn_subscribed = blk2bstr(
diff --git a/lte/gateway/c/oai/tasks/mme_app/mme_config.c b/lte/gateway/c/oai/tasks/mme_app/mme_config.c
index 3db96810e0f9..3d62d6afd98e 100644
--- a/lte/gateway/c/oai/tasks/mme_app/mme_config.c
+++ b/lte/gateway/c/oai/tasks/mme_app/mme_config.c
@@ -63,6 +63,7 @@
#include "bstrlib.h"
#include "mme_default_values.h"
#include "service303.h"
+#include "conversions.h"
#if EMBEDDED_SGW
#include "sgw_config.h"
#endif
@@ -228,6 +229,11 @@ void service303_config_init(service303_data_t* service303_conf) {
service303_conf->version = bfromcstr(SERVICE303_MME_PACKAGE_VERSION);
}
+void blocked_imei_config_init(blocked_imei_list_t* blocked_imeis) {
+ blocked_imeis->num = 0;
+ blocked_imeis->imei_htbl = NULL;
+}
+
//------------------------------------------------------------------------------
void mme_config_init(mme_config_t* config) {
memset(config, 0, sizeof(*config));
@@ -252,6 +258,7 @@ void mme_config_init(mme_config_t* config) {
gummei_config_init(&config->gummei);
served_tai_config_init(&config->served_tai);
service303_config_init(&config->service303_config);
+ blocked_imei_config_init(&config->blocked_imei);
}
//------------------------------------------------------------------------------
@@ -277,6 +284,10 @@ void mme_config_exit(void) {
for (int i = 0; i < mme_config.e_dns_emulation.nb_sgw_entries; i++) {
bdestroy_wrapper(&mme_config.e_dns_emulation.sgw_id[i]);
}
+
+ if (mme_config.blocked_imei.imei_htbl) {
+ hashtable_uint64_ts_destroy(mme_config.blocked_imei.imei_htbl);
+ }
}
//------------------------------------------------------------------------------
@@ -311,6 +322,8 @@ int mme_config_parse_file(mme_config_t* config_pP) {
const char* csfb_mcc = NULL;
const char* csfb_mnc = NULL;
const char* lac = NULL;
+ const char* tac_str = NULL;
+ const char* snr_str = NULL;
config_init(&cfg);
@@ -1043,6 +1056,63 @@ int mme_config_parse_file(mme_config_t* config_pP) {
}
}
+ // BLOCKED IMEI LIST SETTING
+ setting = config_setting_get_member(
+ setting_mme, MME_CONFIG_STRING_BLOCKED_IMEI_LIST);
+ char imei_str[MAX_LEN_IMEI + 1] = {0};
+ imei64_t imei64 = 0;
+ config_pP->blocked_imei.num = 0;
+ OAILOG_INFO(LOG_MME_APP, "MME_CONFIG_STRING_BLOCKED_IMEI_LIST \n");
+ if (setting != NULL) {
+ num = config_setting_length(setting);
+ OAILOG_INFO(LOG_MME_APP, "Number of blocked IMEIs configured =%d\n", num);
+ if (num > 0) {
+ // Create IMEI hashtable
+ hashtable_rc_t h_rc = HASH_TABLE_OK;
+ bstring b = bfromcstr("mme_app_config_imei_htbl");
+ config_pP->blocked_imei.imei_htbl =
+ hashtable_uint64_ts_create(MAX_IMEI_HTBL_SZ, NULL, b);
+ bdestroy_wrapper(&b);
+ AssertFatal(
+ config_pP->blocked_imei.imei_htbl != NULL,
+ "Error creating IMEI hashtable\n");
+
+ for (i = 0; i < num; i++) {
+ memset(imei_str, 0, (MAX_LEN_IMEI + 1));
+ sub2setting = config_setting_get_elem(setting, i);
+ if (sub2setting != NULL) {
+ if ((config_setting_lookup_string(
+ sub2setting, MME_CONFIG_STRING_IMEI_TAC, &tac_str))) {
+ AssertFatal(
+ strlen(tac_str) == MAX_LEN_TAC,
+ "Bad TAC length (%ld), it must be %u digits\n",
+ strlen(tac_str), MAX_LEN_TAC);
+ memcpy(imei_str, tac_str, strlen(tac_str));
+ }
+ if ((config_setting_lookup_string(
+ sub2setting, MME_CONFIG_STRING_SNR, &snr_str))) {
+ if (strlen(snr_str)) {
+ AssertFatal(
+ strlen(snr_str) == MAX_LEN_SNR,
+ "Bad SNR length (%ld), it must be %u digits\n",
+ strlen(snr_str), MAX_LEN_SNR);
+ memcpy(&imei_str[strlen(tac_str)], snr_str, strlen(snr_str));
+ }
+ }
+ // Store IMEI into hashlist
+ imei64 = 0;
+ IMEI_STRING_TO_IMEI64(imei_str, &imei64);
+ h_rc = hashtable_uint64_ts_insert(
+ config_pP->blocked_imei.imei_htbl, (const hash_key_t) imei64,
+ 0);
+ AssertFatal(h_rc == HASH_TABLE_OK, "Hashtable insertion failed\n");
+
+ config_pP->blocked_imei.num += 1;
+ }
+ }
+ }
+ }
+
// NETWORK INTERFACE SETTING
setting = config_setting_get_member(
setting_mme, MME_CONFIG_STRING_NETWORK_INTERFACES_CONFIG);
diff --git a/lte/gateway/c/oai/tasks/nas/emm/Attach.c b/lte/gateway/c/oai/tasks/nas/emm/Attach.c
index 12551442711c..b958b3f94654 100644
--- a/lte/gateway/c/oai/tasks/nas/emm/Attach.c
+++ b/lte/gateway/c/oai/tasks/nas/emm/Attach.c
@@ -138,6 +138,8 @@ static int emm_attach_success_authentication_cb(emm_context_t* emm_context);
static int emm_attach_failure_authentication_cb(emm_context_t* emm_context);
static int emm_attach_success_security_cb(emm_context_t* emm_context);
static int emm_attach_failure_security_cb(emm_context_t* emm_context);
+static int emm_attach_identification_after_smc_success_cb(
+ emm_context_t* emm_context);
/*
Abnormal case attach procedures
@@ -1301,6 +1303,40 @@ static int emm_attach_success_security_cb(emm_context_t* emm_context) {
OAILOG_INFO(LOG_NAS_EMM, "ATTACH - Security procedure success!\n");
nas_emm_attach_proc_t* attach_proc =
get_nas_specific_procedure_attach(emm_context);
+ if (!attach_proc) {
+ OAILOG_ERROR_UE(
+ LOG_NAS_EMM, emm_context->_imsi64,
+ "EMM-PROC - attach_proc is NULL \n");
+ OAILOG_FUNC_RETURN(LOG_NAS_EMM, RETURNerror);
+ }
+
+ if (emm_context->initiate_identity_after_smc) {
+ emm_context->initiate_identity_after_smc = false;
+ OAILOG_DEBUG_UE(
+ LOG_NAS_EMM, emm_context->_imsi64, "Trigger identity procedure\n");
+ rc = emm_proc_identification(
+ emm_context, (nas_emm_proc_t*) attach_proc, IDENTITY_TYPE_2_IMEISV,
+ emm_attach_identification_after_smc_success_cb,
+ emm_attach_failure_identification_cb);
+
+ OAILOG_FUNC_RETURN(LOG_NAS_EMM, rc);
+ }
+
+ rc = emm_attach(emm_context);
+ OAILOG_FUNC_RETURN(LOG_NAS_EMM, rc);
+}
+
+//------------------------------------------------------------------------------
+static int emm_attach_identification_after_smc_success_cb(
+ emm_context_t* emm_context) {
+ OAILOG_FUNC_IN(LOG_NAS_EMM);
+ int rc = RETURNerror;
+
+ OAILOG_INFO(
+ LOG_NAS_EMM,
+ "ATTACH - Identity procedure after smc procedure success!\n");
+ nas_emm_attach_proc_t* attach_proc =
+ get_nas_specific_procedure_attach(emm_context);
if (attach_proc) {
rc = emm_attach(emm_context);
@@ -1761,11 +1797,8 @@ static int emm_send_attach_accept(emm_context_t* emm_context) {
//----------------------------------------
REQUIREMENT_3GPP_24_301(R10_5_5_1_2_4__14);
emm_sap.u.emm_as.u.establish.eps_network_feature_support =
- calloc(1, sizeof(eps_network_feature_support_t));
- emm_sap.u.emm_as.u.establish.eps_network_feature_support->b1 =
- _emm_data.conf.eps_network_feature_support[0];
- emm_sap.u.emm_as.u.establish.eps_network_feature_support->b2 =
- _emm_data.conf.eps_network_feature_support[1];
+ (eps_network_feature_support_t*) &_emm_data.conf
+ .eps_network_feature_support;
/*
* Delete any preexisting UE radio capabilities, pursuant to
@@ -1774,8 +1807,7 @@ static int emm_send_attach_accept(emm_context_t* emm_context) {
// Note: this is safe from double-free errors because it sets to NULL
// after freeing, which free treats as a no-op.
bdestroy_wrapper(&ue_mm_context_p->ue_radio_capability);
- free_wrapper(
- (void**) &emm_sap.u.emm_as.u.establish.eps_network_feature_support);
+
/*
* Setup EPS NAS security data
*/
@@ -1936,14 +1968,9 @@ static int emm_attach_accept_retx(emm_context_t* emm_context) {
"message\n",
ue_id);
emm_sap.u.emm_as.u.establish.eps_network_feature_support =
- calloc(1, sizeof(eps_network_feature_support_t));
+ (eps_network_feature_support_t*) &_emm_data.conf
+ .eps_network_feature_support;
emm_sap.u.emm_as.u.data.new_guti = &emm_context->_guti;
- emm_sap.u.emm_as.u.establish.eps_network_feature_support->b1 =
- _emm_data.conf.eps_network_feature_support[0];
- emm_sap.u.emm_as.u.establish.eps_network_feature_support->b2 =
- _emm_data.conf.eps_network_feature_support[1];
- free_wrapper(
- (void**) &emm_sap.u.emm_as.u.establish.eps_network_feature_support);
/*
* Setup EPS NAS security data
diff --git a/lte/gateway/c/oai/tasks/nas/emm/Identification.c b/lte/gateway/c/oai/tasks/nas/emm/Identification.c
index e9a25be6ffb5..fa2fcac232d8 100644
--- a/lte/gateway/c/oai/tasks/nas/emm/Identification.c
+++ b/lte/gateway/c/oai/tasks/nas/emm/Identification.c
@@ -46,7 +46,7 @@
/**************** E X T E R N A L D E F I N I T I O N S ****************/
/****************************************************************************/
extern int check_plmn_restriction(imsi_t imsi);
-
+extern int validate_imei(imeisv_t* imeisv);
/****************************************************************************/
/******************* L O C A L D E F I N I T I O N S *******************/
/****************************************************************************/
@@ -244,9 +244,18 @@ int emm_proc_identification_complete(
*/
emm_ctx_set_valid_imei(emm_ctx, imei);
} else if (imeisv) {
- /*
- * Update the IMEISV
- */
+ // Validate IMEI
+ int emm_cause = validate_imei(imeisv);
+ if (emm_cause != EMM_CAUSE_SUCCESS) {
+ OAILOG_ERROR(
+ LOG_NAS_EMM,
+ "EMMAS-SAP - Sending Attach Reject for ue_id =" MME_UE_S1AP_ID_FMT
+ " , emm_cause =(%d)\n",
+ ue_id, emm_cause);
+ rc = emm_proc_attach_reject(ue_id, emm_cause);
+ OAILOG_FUNC_RETURN(LOG_NAS_EMM, rc);
+ }
+ // Update the IMEISV
emm_ctx_set_valid_imeisv(emm_ctx, imeisv);
} else if (tmsi) {
/*
diff --git a/lte/gateway/c/oai/tasks/nas/emm/SecurityModeControl.c b/lte/gateway/c/oai/tasks/nas/emm/SecurityModeControl.c
index c3498111bb94..eaf445c0fe6e 100644
--- a/lte/gateway/c/oai/tasks/nas/emm/SecurityModeControl.c
+++ b/lte/gateway/c/oai/tasks/nas/emm/SecurityModeControl.c
@@ -66,6 +66,7 @@
#include "3gpp_36.401.h"
#include "NasSecurityAlgorithms.h"
#include "emm_asDef.h"
+#include "emm_cause.h"
#include "emm_cnDef.h"
#include "emm_fsm.h"
#include "emm_regDef.h"
@@ -75,6 +76,7 @@
#include "nas/securityDef.h"
#include "security_types.h"
#include "mme_app_defs.h"
+#include "conversions.h"
/****************************************************************************/
/**************** E X T E R N A L D E F I N I T I O N S ****************/
@@ -375,6 +377,53 @@ int emm_proc_security_mode_control(
OAILOG_FUNC_RETURN(LOG_NAS_EMM, rc);
}
+/****************************************************************************
+ ** **
+ ** Name: validate_imei() **
+ ** **
+ ** Description: Check if the received imei matches with the **
+ ** blocked imei list **
+ ** **
+ ** Inputs: imei/imeisv string : imei received in security mode **
+ ** complete/attach req **
+ ** Outputs: **
+ ** Return: EMM cause **
+ ** Others: None **
+ ** **
+ ***************************************************************************/
+int validate_imei(imeisv_t* imeisv) {
+ OAILOG_FUNC_IN(LOG_NAS_EMM);
+ /* First convert only TAC to uint64_t. If TAC is not found in the hashlist,
+ * convert IMEI(TAC + SNR) into uint64_t and check if the key is found
+ * the hashlist
+ */
+ imei64_t tac64 = 0;
+ if (!mme_config.blocked_imei.num) {
+ OAILOG_DEBUG(LOG_NAS_EMM, "No Blocked IMEI exists, returning success!");
+ OAILOG_FUNC_RETURN(LOG_NAS_EMM, EMM_CAUSE_SUCCESS);
+ } else {
+ OAILOG_DEBUG(
+ LOG_NAS_EMM, "Blocked IMEI exists, proceed with validation...");
+ }
+ IMEI_MOBID_TO_IMEI_TAC64(imeisv, &tac64);
+ hashtable_rc_t h_rc = hashtable_uint64_ts_is_key_exists(
+ mme_config.blocked_imei.imei_htbl, (const hash_key_t) tac64);
+
+ if (HASH_TABLE_OK == h_rc) {
+ OAILOG_FUNC_RETURN(LOG_NAS_EMM, EMM_CAUSE_IMEI_NOT_ACCEPTED);
+ } else {
+ // Convert imei to uint64_t
+ imei64_t imei64 = 0;
+ IMEI_MOBID_TO_IMEI64(imeisv, &imei64);
+ hashtable_rc_t h_rc = hashtable_uint64_ts_is_key_exists(
+ mme_config.blocked_imei.imei_htbl, (const hash_key_t) imei64);
+ if (HASH_TABLE_OK == h_rc) {
+ OAILOG_FUNC_RETURN(LOG_NAS_EMM, EMM_CAUSE_IMEI_NOT_ACCEPTED);
+ }
+ }
+ OAILOG_FUNC_RETURN(LOG_NAS_EMM, EMM_CAUSE_SUCCESS);
+}
+
/****************************************************************************
** **
** Name: emm_proc_security_mode_complete() **
@@ -414,6 +463,14 @@ int emm_proc_security_mode_complete(
ue_mm_context = mme_ue_context_exists_mme_ue_s1ap_id(ue_id);
if (ue_mm_context) {
emm_ctx = &ue_mm_context->emm_context;
+ if (!emm_ctx) {
+ OAILOG_ERROR(
+ LOG_NAS_EMM,
+ "EMM-PROC - emm context is NULL for (ue_id=" MME_UE_S1AP_ID_FMT
+ ")\n",
+ ue_id);
+ OAILOG_FUNC_RETURN(LOG_NAS_EMM, RETURNerror);
+ }
} else {
OAILOG_FUNC_RETURN(LOG_NAS_EMM, RETURNerror);
}
@@ -429,7 +486,14 @@ int emm_proc_security_mode_complete(
void* timer_callback_arg = NULL;
nas_stop_T3460(ue_id, &smc_proc->T3460, timer_callback_arg);
- if (imeisvmob) {
+ /* If MME requested for imeisv in security mode cmd
+ * and UE did not include the same in security mode complete,
+ * set initiate_identity_after_smc flag to send identity request
+ * with identity type set to imeisv
+ */
+ if (smc_proc->imeisv_request && !imeisvmob) {
+ emm_ctx->initiate_identity_after_smc = true;
+ } else if (smc_proc->imeisv_request && imeisvmob) {
imeisv_t imeisv = {0};
imeisv.u.num.tac1 = imeisvmob->tac1;
imeisv.u.num.tac2 = imeisvmob->tac2;
@@ -448,6 +512,17 @@ int emm_proc_security_mode_complete(
imeisv.u.num.svn1 = imeisvmob->svn1;
imeisv.u.num.svn2 = imeisvmob->svn2;
imeisv.u.num.parity = imeisvmob->oddeven;
+
+ int emm_cause = validate_imei(&imeisv);
+ if (emm_cause != EMM_CAUSE_SUCCESS) {
+ OAILOG_ERROR(
+ LOG_NAS_EMM,
+ "EMMAS-SAP - Sending Attach Reject for ue_id =" MME_UE_S1AP_ID_FMT
+ " , emm_cause =(%d)\n",
+ ue_id, emm_cause);
+ rc = emm_proc_attach_reject(ue_id, emm_cause);
+ OAILOG_FUNC_RETURN(LOG_NAS_EMM, rc);
+ }
emm_ctx_set_valid_imeisv(emm_ctx, &imeisv);
}
diff --git a/lte/gateway/c/oai/tasks/nas/emm/emm_data.h b/lte/gateway/c/oai/tasks/nas/emm/emm_data.h
index a62d0b105e8f..e35522a369c0 100644
--- a/lte/gateway/c/oai/tasks/nas/emm/emm_data.h
+++ b/lte/gateway/c/oai/tasks/nas/emm/emm_data.h
@@ -371,6 +371,7 @@ typedef struct emm_context_s {
*/
bool nw_init_bearer_deactv;
new_attach_info_t* new_attach_info;
+ bool initiate_identity_after_smc;
} emm_context_t;
/*
diff --git a/lte/gateway/c/oai/tasks/nas/emm/msg/emm_msg.c b/lte/gateway/c/oai/tasks/nas/emm/msg/emm_msg.c
index c32f214b3832..1d560020fa95 100644
--- a/lte/gateway/c/oai/tasks/nas/emm/msg/emm_msg.c
+++ b/lte/gateway/c/oai/tasks/nas/emm/msg/emm_msg.c
@@ -174,12 +174,11 @@ int emm_msg_decode(EMM_msg* msg, uint8_t* buffer, uint32_t len) {
case SECURITY_MODE_COMPLETE:
decode_result = decode_security_mode_complete(
&msg->security_mode_complete, buffer, len);
- // MAX_IMEISV_SIZE is defined as 15, but IMEISV is
- // actually 16 digits. Extra char for null termination.
- char imeisv[MAX_IMEISV_SIZE + 2];
+ // IMEISV is 16 digits. Extra char for null termination.
+ char imeisv[MAX_IMEISV_SIZE + 1];
IMEISV_MOBID_TO_STRING(
&msg->security_mode_complete.imeisv.imeisv, imeisv,
- MAX_IMEISV_SIZE + 2);
+ MAX_IMEISV_SIZE + 1);
OAILOG_INFO(LOG_NAS_EMM, "EMM-MSG - IMEISV: %s", imeisv);
break;
diff --git a/lte/gateway/c/oai/tasks/nas/emm/sap/emm_cn.c b/lte/gateway/c/oai/tasks/nas/emm/sap/emm_cn.c
index 4dba0d73b0b9..c3f8398e8282 100644
--- a/lte/gateway/c/oai/tasks/nas/emm/sap/emm_cn.c
+++ b/lte/gateway/c/oai/tasks/nas/emm/sap/emm_cn.c
@@ -571,8 +571,8 @@ static int emm_cn_cs_response_success(emm_cn_cs_response_success_t* msg_pP) {
rc = esm_send_activate_default_eps_bearer_context_request(
msg_pP->pti, msg_pP->ebi,
&esm_msg.activate_default_eps_bearer_context_request,
- ue_mm_context->pdn_contexts[pdn_cid]->apn_subscribed, &msg_pP->pco,
- esm_pdn_type, msg_pP->pdn_addr, &qos,
+ ue_mm_context->pdn_contexts[pdn_cid], &msg_pP->pco, esm_pdn_type,
+ msg_pP->pdn_addr, &qos,
ue_mm_context->pdn_contexts[pdn_cid]->esm_data.esm_cause);
clear_protocol_configuration_options(&msg_pP->pco);
if (rc != RETURNerror) {
diff --git a/lte/gateway/c/oai/tasks/nas/emm/sap/emm_send.c b/lte/gateway/c/oai/tasks/nas/emm/sap/emm_send.c
index fe4a5d22dc74..b198bad8657d 100644
--- a/lte/gateway/c/oai/tasks/nas/emm/sap/emm_send.c
+++ b/lte/gateway/c/oai/tasks/nas/emm/sap/emm_send.c
@@ -1308,6 +1308,8 @@ int emm_send_identity_request(
emm_msg->identitytype = IDENTITY_TYPE_2_TMSI;
} else if (msg->ident_type == IDENTITY_TYPE_2_IMEI) {
emm_msg->identitytype = IDENTITY_TYPE_2_IMEI;
+ } else if (msg->ident_type == IDENTITY_TYPE_2_IMEISV) {
+ emm_msg->identitytype = IDENTITY_TYPE_2_IMEISV;
} else {
/*
* All other values are interpreted as "IMSI"
diff --git a/lte/gateway/c/oai/tasks/nas/esm/sap/esm_send.c b/lte/gateway/c/oai/tasks/nas/esm/sap/esm_send.c
index decab67bb4e7..6cb02ec321b2 100644
--- a/lte/gateway/c/oai/tasks/nas/esm/sap/esm_send.c
+++ b/lte/gateway/c/oai/tasks/nas/esm/sap/esm_send.c
@@ -220,12 +220,14 @@ int esm_send_pdn_disconnect_reject(
***************************************************************************/
int esm_send_activate_default_eps_bearer_context_request(
pti_t pti, ebi_t ebi, activate_default_eps_bearer_context_request_msg* msg,
- bstring apn, const protocol_configuration_options_t* pco, int pdn_type,
- bstring pdn_addr, const EpsQualityOfService* qos, int esm_cause) {
+ pdn_context_t* pdn_context_p, const protocol_configuration_options_t* pco,
+ int pdn_type, bstring pdn_addr, const EpsQualityOfService* qos,
+ int esm_cause) {
OAILOG_FUNC_IN(LOG_NAS_ESM);
OAILOG_INFO(
LOG_NAS_ESM,
"ESM-SAP - Send Activate Default EPS Bearer Context Request message\n");
+ bstring apn = pdn_context_p->apn_subscribed;
/*
* Mandatory - ESM message header
*/
@@ -312,20 +314,16 @@ int esm_send_activate_default_eps_bearer_context_request(
&msg->protocolconfigurationoptions, pco);
}
//#pragma message "TEST LG FORCE APN-AMBR"
- OAILOG_DEBUG(LOG_NAS_ESM, "ESM-SAP - FORCE APN-AMBR\n");
+ OAILOG_DEBUG(
+ LOG_NAS_ESM, "ESM-SAP - FORCE APN-AMBR DL %lu UL %lu\n",
+ pdn_context_p->subscribed_apn_ambr.br_dl,
+ pdn_context_p->subscribed_apn_ambr.br_ul);
msg->presencemask |=
ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST_APNAMBR_PRESENT;
- // APN AMBR is hardcoded to DL AMBR = 200 Mbps and UL APN MBR = 100 Mbps -
- // Which is ok for now for TDD 20 MHz
- // TODO task#14477798 - need to change these to apm-subscribed values
- msg->apnambr.apnambrfordownlink = 0xfe; // (8640kbps)
- msg->apnambr.apnambrforuplink = 0xfe; // (8640kbps)
- msg->apnambr.apnambrfordownlink_extended = 0xde; // (200Mbps)
- msg->apnambr.apnambrforuplink_extended = 0x9e; // (100Mbps)
- msg->apnambr.apnambrfordownlink_extended2 = 0;
- msg->apnambr.apnambrforuplink_extended2 = 0;
- msg->apnambr.extensions =
- 0 | APN_AGGREGATE_MAXIMUM_BIT_RATE_MAXIMUM_EXTENSION_PRESENT;
+ bit_rate_value_to_eps_qos(
+ &msg->apnambr, pdn_context_p->subscribed_apn_ambr.br_dl,
+ pdn_context_p->subscribed_apn_ambr.br_ul);
+
OAILOG_INFO(
LOG_NAS_ESM,
"ESM-SAP - Send Activate Default EPS Bearer Context "
diff --git a/lte/gateway/c/oai/tasks/nas/esm/sap/esm_send.h b/lte/gateway/c/oai/tasks/nas/esm/sap/esm_send.h
index 6245926dba80..37a2c4c3f889 100644
--- a/lte/gateway/c/oai/tasks/nas/esm/sap/esm_send.h
+++ b/lte/gateway/c/oai/tasks/nas/esm/sap/esm_send.h
@@ -51,6 +51,7 @@ Description Defines functions executed at the ESM Service Access
#include "3gpp_24.008.h"
#include "EpsQualityOfService.h"
#include "bstrlib.h"
+#include "mme_app_ue_context.h"
/****************************************************************************/
/********************* G L O B A L C O N S T A N T S *******************/
@@ -94,8 +95,9 @@ int esm_send_pdn_disconnect_reject(
*/
int esm_send_activate_default_eps_bearer_context_request(
pti_t pti, ebi_t ebi, activate_default_eps_bearer_context_request_msg* msg,
- bstring apn, const protocol_configuration_options_t* pco, int pdn_type,
- bstring pdn_addr, const EpsQualityOfService* qos, int esm_cause);
+ pdn_context_t* pdn_context_p, const protocol_configuration_options_t* pco,
+ int pdn_type, bstring pdn_addr, const EpsQualityOfService* qos,
+ int esm_cause);
int esm_send_activate_dedicated_eps_bearer_context_request(
pti_t pti, ebi_t ebi,
diff --git a/lte/gateway/c/oai/tasks/nas/ies/ApnAggregateMaximumBitRate.c b/lte/gateway/c/oai/tasks/nas/ies/ApnAggregateMaximumBitRate.c
index 164287eea9dd..8e8396f8dc1e 100644
--- a/lte/gateway/c/oai/tasks/nas/ies/ApnAggregateMaximumBitRate.c
+++ b/lte/gateway/c/oai/tasks/nas/ies/ApnAggregateMaximumBitRate.c
@@ -107,3 +107,58 @@ int encode_apn_aggregate_maximum_bit_rate(
*lenPtr = encoded - 1 - ((iei > 0) ? 1 : 0);
return encoded;
}
+
+// Use 3GPP TS 24.008 figure 10.5.136A, table 10.5.154A
+void bit_rate_value_to_eps_qos(
+ ApnAggregateMaximumBitRate* apn_ambr, uint64_t ambr_dl, uint64_t ambr_ul) {
+ uint64_t ambr_dl_kbps = ambr_dl / 1000; // ambr_dl is expected in bps
+ uint64_t ambr_ul_kbps = ambr_ul / 1000; // ambr_ul is expected in bps
+ if (ambr_dl_kbps == 0) {
+ apn_ambr->apnambrfordownlink = 0xff;
+ } else if ((ambr_dl_kbps > 0) && (ambr_dl_kbps <= 63)) {
+ apn_ambr->apnambrfordownlink = ambr_dl_kbps;
+ } else if ((ambr_dl_kbps > 63) && (ambr_dl_kbps <= 575)) {
+ apn_ambr->apnambrfordownlink = ((ambr_dl_kbps - 64) / 8) + 64;
+ } else if ((ambr_dl_kbps > 575) && (ambr_dl_kbps <= 8640)) {
+ apn_ambr->apnambrfordownlink = ((ambr_dl_kbps - 576) / 64) + 128;
+ } else if (ambr_dl_kbps > 8640) {
+ apn_ambr->apnambrfordownlink = 0xfe;
+ apn_ambr->extensions =
+ APN_AGGREGATE_MAXIMUM_BIT_RATE_MAXIMUM_EXTENSION_PRESENT;
+ if ((ambr_dl_kbps >= 8600) && (ambr_dl_kbps <= 16000)) {
+ apn_ambr->apnambrfordownlink_extended = (ambr_dl_kbps - 8600) / 100;
+ } else if ((ambr_dl_kbps > 16000) && (ambr_dl_kbps <= 128000)) {
+ apn_ambr->apnambrfordownlink_extended =
+ ((ambr_dl_kbps - 16000) / 1000) + 74;
+ } else if ((ambr_dl_kbps > 128000) && (ambr_dl_kbps <= 256000)) {
+ apn_ambr->apnambrfordownlink_extended =
+ ((ambr_dl_kbps - 128000) / 2000) + 186;
+ }
+ }
+
+ if (ambr_ul_kbps == 0) {
+ apn_ambr->apnambrforuplink = 0xff;
+ } else if ((ambr_ul_kbps > 0) && (ambr_ul_kbps <= 63)) {
+ apn_ambr->apnambrforuplink = ambr_ul_kbps;
+ } else if ((ambr_ul_kbps > 63) && (ambr_ul_kbps <= 575)) {
+ apn_ambr->apnambrforuplink = ((ambr_ul_kbps - 64) / 8) + 64;
+ } else if ((ambr_ul_kbps > 575) && (ambr_ul_kbps <= 8640)) {
+ apn_ambr->apnambrforuplink = ((ambr_ul_kbps - 576) / 64) + 128;
+ } else if (ambr_ul_kbps > 8640) {
+ apn_ambr->apnambrforuplink = 0xfe;
+ apn_ambr->extensions =
+ APN_AGGREGATE_MAXIMUM_BIT_RATE_MAXIMUM_EXTENSION_PRESENT;
+ if ((ambr_ul_kbps >= 8600) && (ambr_ul_kbps <= 16000)) {
+ apn_ambr->apnambrforuplink_extended = (ambr_ul_kbps - 8600) / 100;
+ } else if ((ambr_ul_kbps > 16000) && (ambr_ul_kbps <= 128000)) {
+ apn_ambr->apnambrforuplink_extended =
+ ((ambr_ul_kbps - 16000) / 1000) + 74;
+ } else if ((ambr_ul_kbps > 128000) && (ambr_ul_kbps <= 256000)) {
+ apn_ambr->apnambrforuplink_extended =
+ ((ambr_ul_kbps - 128000) / 2000) + 186;
+ }
+ }
+
+ apn_ambr->apnambrfordownlink_extended2 = 0;
+ apn_ambr->apnambrforuplink_extended2 = 0;
+}
diff --git a/lte/gateway/c/oai/tasks/nas/ies/ApnAggregateMaximumBitRate.h b/lte/gateway/c/oai/tasks/nas/ies/ApnAggregateMaximumBitRate.h
index d0ae7075aad2..35e76eb6656e 100644
--- a/lte/gateway/c/oai/tasks/nas/ies/ApnAggregateMaximumBitRate.h
+++ b/lte/gateway/c/oai/tasks/nas/ies/ApnAggregateMaximumBitRate.h
@@ -44,4 +44,7 @@ int decode_apn_aggregate_maximum_bit_rate(
ApnAggregateMaximumBitRate* apnaggregatemaximumbitrate, uint8_t iei,
uint8_t* buffer, uint32_t len);
+void bit_rate_value_to_eps_qos(
+ ApnAggregateMaximumBitRate* apn_ambr, uint64_t ambr_dl, uint64_t ambr_ul);
+
#endif /* APN_AGGREGATE_MAXIMUM_BIT_RATE_SEEN */
diff --git a/lte/gateway/c/oai/tasks/nas/ies/EpsQualityOfService.c b/lte/gateway/c/oai/tasks/nas/ies/EpsQualityOfService.c
index 74aacaeba7f0..cd4fa5836bd8 100644
--- a/lte/gateway/c/oai/tasks/nas/ies/EpsQualityOfService.c
+++ b/lte/gateway/c/oai/tasks/nas/ies/EpsQualityOfService.c
@@ -178,92 +178,98 @@ int qos_params_to_eps_qos(
const qci_t qci, const bitrate_t mbr_dl, const bitrate_t mbr_ul,
const bitrate_t gbr_dl, const bitrate_t gbr_ul,
EpsQualityOfService* const eps_qos, bool is_default_bearer) {
- // if someone volunteer for subroutines..., no time yet.
+ uint64_t mbr_dl_kbps = mbr_dl / 1000; // mbr_dl is expected in bps
+ uint64_t mbr_ul_kbps = mbr_ul / 1000; // mbr_ul is expected in bps
+ uint64_t gbr_dl_kbps = gbr_dl / 1000; // mbr_dl is expected in bps
+ uint64_t gbr_ul_kbps = gbr_ul / 1000; // mbr_ul is expected in bps
+
if (eps_qos) {
memset(eps_qos, 0, sizeof(EpsQualityOfService));
eps_qos->qci = qci;
if (!is_default_bearer) {
eps_qos->bitRatesPresent = 1;
- if (mbr_ul == 0) {
+ if (mbr_ul_kbps == 0) {
eps_qos->bitRates.maxBitRateForUL = 0xff;
- } else if ((mbr_ul > 0) && (mbr_ul <= 63)) {
- eps_qos->bitRates.maxBitRateForUL = mbr_ul;
- } else if ((mbr_ul > 63) && (mbr_ul <= 568)) {
- eps_qos->bitRates.maxBitRateForUL = ((mbr_ul - 64) / 8) + 64;
- } else if ((mbr_ul >= 576) && (mbr_ul <= 8640)) {
- eps_qos->bitRates.maxBitRateForUL = ((mbr_ul - 128) / 64) + 128;
- } else if (mbr_ul > 8640) {
+ } else if ((mbr_ul_kbps > 0) && (mbr_ul_kbps <= 63)) {
+ eps_qos->bitRates.maxBitRateForUL = mbr_ul_kbps;
+ } else if ((mbr_ul_kbps > 63) && (mbr_ul_kbps <= 575)) {
+ eps_qos->bitRates.maxBitRateForUL = ((mbr_ul_kbps - 64) / 8) + 64;
+ } else if ((mbr_ul_kbps > 575) && (mbr_ul_kbps <= 8640)) {
+ eps_qos->bitRates.maxBitRateForUL = ((mbr_ul_kbps - 576) / 64) + 128;
+ } else if (mbr_ul_kbps > 8640) {
eps_qos->bitRates.maxBitRateForUL = 0xfe;
eps_qos->bitRatesExtPresent = 1;
- if ((mbr_ul >= 8600) && (mbr_ul <= 16000)) {
- eps_qos->bitRatesExt.maxBitRateForUL = (mbr_ul - 8600) / 100;
- } else if ((mbr_ul > 16000) && (mbr_ul <= 128000)) {
- eps_qos->bitRatesExt.maxBitRateForUL = ((mbr_ul - 16000) / 1000) + 74;
- } else if ((mbr_ul > 128000) && (mbr_ul <= 256000)) {
+ if ((mbr_ul_kbps >= 8600) && (mbr_ul_kbps <= 16000)) {
+ eps_qos->bitRatesExt.maxBitRateForUL = (mbr_ul_kbps - 8600) / 100;
+ } else if ((mbr_ul_kbps > 16000) && (mbr_ul_kbps <= 128000)) {
+ eps_qos->bitRatesExt.maxBitRateForUL =
+ ((mbr_ul_kbps - 16000) / 1000) + 74;
+ } else if ((mbr_ul_kbps > 128000) && (mbr_ul_kbps <= 256000)) {
eps_qos->bitRatesExt.maxBitRateForUL =
- ((mbr_ul - 128000) / 2000) + 186;
+ ((mbr_ul_kbps - 128000) / 2000) + 186;
}
}
- if (mbr_dl == 0) {
+ if (mbr_dl_kbps == 0) {
eps_qos->bitRates.maxBitRateForDL = 0xff;
- } else if ((mbr_dl > 0) && (mbr_dl <= 63)) {
- eps_qos->bitRates.maxBitRateForDL = mbr_dl;
- } else if ((mbr_dl > 63) && (mbr_dl <= 568)) {
- eps_qos->bitRates.maxBitRateForDL = ((mbr_dl - 64) / 8) + 64;
- } else if ((mbr_dl >= 576) && (mbr_dl <= 8640)) {
- eps_qos->bitRates.maxBitRateForDL = ((mbr_dl - 128) / 64) + 128;
- } else if (mbr_dl > 8640) {
+ } else if ((mbr_dl_kbps > 0) && (mbr_dl_kbps <= 63)) {
+ eps_qos->bitRates.maxBitRateForDL = mbr_dl_kbps;
+ } else if ((mbr_dl_kbps > 63) && (mbr_dl_kbps <= 575)) {
+ eps_qos->bitRates.maxBitRateForDL = ((mbr_dl_kbps - 64) / 8) + 64;
+ } else if ((mbr_dl_kbps > 575) && (mbr_dl_kbps <= 8640)) {
+ eps_qos->bitRates.maxBitRateForDL = ((mbr_dl_kbps - 576) / 64) + 128;
+ } else if (mbr_dl_kbps > 8640) {
eps_qos->bitRates.maxBitRateForDL = 0xfe;
eps_qos->bitRatesExtPresent = 1;
- if ((mbr_dl >= 8600) && (mbr_dl <= 16000)) {
- eps_qos->bitRatesExt.maxBitRateForDL = (mbr_dl - 8600) / 100;
- } else if ((mbr_dl > 16000) && (mbr_dl <= 128000)) {
- eps_qos->bitRatesExt.maxBitRateForDL = ((mbr_dl - 16000) / 1000) + 74;
- } else if ((mbr_dl > 128000) && (mbr_dl <= 256000)) {
+ if ((mbr_dl_kbps >= 8600) && (mbr_dl_kbps <= 16000)) {
+ eps_qos->bitRatesExt.maxBitRateForDL = (mbr_dl_kbps - 8600) / 100;
+ } else if ((mbr_dl_kbps > 16000) && (mbr_dl_kbps <= 128000)) {
+ eps_qos->bitRatesExt.maxBitRateForDL =
+ ((mbr_dl_kbps - 16000) / 1000) + 74;
+ } else if ((mbr_dl_kbps > 128000) && (mbr_dl_kbps <= 256000)) {
eps_qos->bitRatesExt.maxBitRateForDL =
- ((mbr_dl - 128000) / 2000) + 186;
+ ((mbr_dl_kbps - 128000) / 2000) + 186;
}
}
- if (gbr_ul == 0) {
+ if (gbr_ul_kbps == 0) {
eps_qos->bitRates.guarBitRateForUL = 0xff;
- } else if ((gbr_ul > 0) && (gbr_ul <= 63)) {
- eps_qos->bitRates.guarBitRateForUL = gbr_ul;
- } else if ((gbr_ul > 63) && (gbr_ul <= 568)) {
- eps_qos->bitRates.guarBitRateForUL = ((gbr_ul - 64) / 8) + 64;
- } else if ((gbr_ul >= 576) && (gbr_ul <= 8640)) {
- eps_qos->bitRates.guarBitRateForUL = ((gbr_ul - 128) / 64) + 128;
- } else if (gbr_ul > 8640) {
+ } else if ((gbr_ul_kbps > 0) && (gbr_ul_kbps <= 63)) {
+ eps_qos->bitRates.guarBitRateForUL = gbr_ul_kbps;
+ } else if ((gbr_ul_kbps > 63) && (gbr_ul_kbps <= 575)) {
+ eps_qos->bitRates.guarBitRateForUL = ((gbr_ul_kbps - 64) / 8) + 64;
+ } else if ((gbr_ul_kbps > 575) && (gbr_ul_kbps <= 8640)) {
+ eps_qos->bitRates.guarBitRateForUL = ((gbr_ul_kbps - 576) / 64) + 128;
+ } else if (gbr_ul_kbps > 8640) {
eps_qos->bitRates.guarBitRateForUL = 0xfe;
eps_qos->bitRatesExtPresent = 1;
- if ((gbr_ul >= 8600) && (gbr_ul <= 16000)) {
- eps_qos->bitRatesExt.guarBitRateForUL = (gbr_ul - 8600) / 100;
- } else if ((gbr_ul > 16000) && (gbr_ul <= 128000)) {
+ if ((gbr_ul_kbps >= 8600) && (gbr_ul_kbps <= 16000)) {
+ eps_qos->bitRatesExt.guarBitRateForUL = (gbr_ul_kbps - 8600) / 100;
+ } else if ((gbr_ul_kbps > 16000) && (gbr_ul_kbps <= 128000)) {
eps_qos->bitRatesExt.guarBitRateForUL =
- ((gbr_ul - 16000) / 1000) + 74;
- } else if ((gbr_ul > 128000) && (gbr_ul <= 256000)) {
+ ((gbr_ul_kbps - 16000) / 1000) + 74;
+ } else if ((gbr_ul_kbps > 128000) && (gbr_ul_kbps <= 256000)) {
eps_qos->bitRatesExt.guarBitRateForUL =
- ((gbr_ul - 128000) / 2000) + 186;
+ ((gbr_ul_kbps - 128000) / 2000) + 186;
}
}
- if (gbr_dl == 0) {
+ if (gbr_dl_kbps == 0) {
eps_qos->bitRates.guarBitRateForDL = 0xff;
- } else if ((gbr_dl > 0) && (gbr_dl <= 63)) {
- eps_qos->bitRates.guarBitRateForDL = gbr_dl;
- } else if ((gbr_dl > 63) && (gbr_dl <= 568)) {
- eps_qos->bitRates.guarBitRateForDL = ((gbr_dl - 64) / 8) + 64;
- } else if ((gbr_dl >= 576) && (gbr_dl <= 8640)) {
- eps_qos->bitRates.guarBitRateForDL = ((gbr_dl - 128) / 64) + 128;
- } else if (gbr_dl > 8640) {
+ } else if ((gbr_dl_kbps > 0) && (gbr_dl_kbps <= 63)) {
+ eps_qos->bitRates.guarBitRateForDL = gbr_dl_kbps;
+ } else if ((gbr_dl_kbps > 63) && (gbr_dl_kbps <= 575)) {
+ eps_qos->bitRates.guarBitRateForDL = ((gbr_dl_kbps - 64) / 8) + 64;
+ } else if ((gbr_dl_kbps >= 575) && (gbr_dl_kbps <= 8640)) {
+ eps_qos->bitRates.guarBitRateForDL = ((gbr_dl_kbps - 576) / 64) + 128;
+ } else if (gbr_dl_kbps > 8640) {
eps_qos->bitRates.guarBitRateForDL = 0xfe;
eps_qos->bitRatesExtPresent = 1;
- if ((gbr_dl >= 8600) && (gbr_dl <= 16000)) {
- eps_qos->bitRatesExt.guarBitRateForDL = (gbr_dl - 8600) / 100;
- } else if ((gbr_dl > 16000) && (gbr_dl <= 128000)) {
+ if ((gbr_dl_kbps >= 8600) && (gbr_dl_kbps <= 16000)) {
+ eps_qos->bitRatesExt.guarBitRateForDL = (gbr_dl_kbps - 8600) / 100;
+ } else if ((gbr_dl_kbps > 16000) && (gbr_dl_kbps <= 128000)) {
eps_qos->bitRatesExt.guarBitRateForDL =
- ((gbr_dl - 16000) / 1000) + 74;
- } else if ((gbr_dl > 128000) && (gbr_dl <= 256000)) {
+ ((gbr_dl_kbps - 16000) / 1000) + 74;
+ } else if ((gbr_dl_kbps > 128000) && (gbr_dl_kbps <= 256000)) {
eps_qos->bitRatesExt.guarBitRateForDL =
- ((gbr_dl - 128000) / 2000) + 186;
+ ((gbr_dl_kbps - 128000) / 2000) + 186;
}
}
}
diff --git a/lte/gateway/c/oai/tasks/ngap/ngap_state_manager.cpp b/lte/gateway/c/oai/tasks/ngap/ngap_state_manager.cpp
index 65eb79ddb689..2771c4f8b2da 100644
--- a/lte/gateway/c/oai/tasks/ngap/ngap_state_manager.cpp
+++ b/lte/gateway/c/oai/tasks/ngap/ngap_state_manager.cpp
@@ -33,7 +33,8 @@ using magma::lte::oai::Ngap_UeDescription;
namespace magma5g {
-NgapStateManager::NgapStateManager() : max_gnbs_(0), max_ues_(0) {}
+NgapStateManager::NgapStateManager()
+ : max_gnbs_(0), max_ues_(0), ngap_imsi_map_hash_(0) {}
NgapStateManager::~NgapStateManager() {
free_state();
@@ -107,7 +108,6 @@ void NgapStateManager::free_state() {
ht_rc = hashtable_ts_get(
&state_cache_p->gnbs, (hash_key_t) assoc_id, (void**) &gnb);
AssertFatal(ht_rc == HASH_TABLE_OK, "eNB UE id not in assoc_id");
- AssertFatal(ht_rc == HASH_TABLE_OK, "eNB UE id not in assoc_id");
}
FREE_HASHTABLE_KEY_ARRAY(keys);
}
@@ -182,7 +182,13 @@ void NgapStateManager::put_ngap_imsi_map() {
}
oai::NgapImsiMap imsi_proto = oai::NgapImsiMap();
NgapStateConverter::ngap_imsi_map_to_proto(ngap_imsi_map_, &imsi_proto);
- redis_client->write_proto(NGAP_IMSI_MAP_TABLE_NAME, imsi_proto);
+ std::string proto_msg;
+ redis_client->serialize(imsi_proto, proto_msg);
+ std::size_t new_hash = std::hash{}(proto_msg);
+ if (new_hash != this->ngap_imsi_map_hash_) {
+ redis_client->write_proto_str(NGAP_IMSI_MAP_TABLE_NAME, proto_msg, 0);
+ this->ngap_imsi_map_hash_ = new_hash;
+ }
}
} // namespace magma5g
diff --git a/lte/gateway/c/oai/tasks/ngap/ngap_state_manager.h b/lte/gateway/c/oai/tasks/ngap/ngap_state_manager.h
index 11bb94b3fd23..303126810a7b 100644
--- a/lte/gateway/c/oai/tasks/ngap/ngap_state_manager.h
+++ b/lte/gateway/c/oai/tasks/ngap/ngap_state_manager.h
@@ -110,5 +110,6 @@ class NgapStateManager
uint32_t max_ues_;
uint32_t max_gnbs_;
ngap_imsi_map_t* ngap_imsi_map_;
+ std::size_t ngap_imsi_map_hash_;
};
} // namespace magma5g
diff --git a/lte/gateway/c/oai/tasks/s1ap/s1ap_mme.c b/lte/gateway/c/oai/tasks/s1ap/s1ap_mme.c
index bbfc9adf646b..9b1d762b5f44 100644
--- a/lte/gateway/c/oai/tasks/s1ap/s1ap_mme.c
+++ b/lte/gateway/c/oai/tasks/s1ap/s1ap_mme.c
@@ -112,12 +112,16 @@ static int handle_message(zloop_t* loop, zsock_t* reader, void* arg) {
state = get_s1ap_state(false);
AssertFatal(state != NULL, "failed to retrieve s1ap state (was null)");
+ bool is_state_same = false;
+
switch (ITTI_MSG_ID(received_message_p)) {
case ACTIVATE_MESSAGE: {
+ is_state_same = true; // does not modify state
hss_associated = true;
} break;
case MESSAGE_TEST:
+ is_state_same = true; // does not modify state
OAILOG_DEBUG(LOG_S1AP, "Received MESSAGE_TEST\n");
break;
@@ -145,6 +149,7 @@ static int handle_message(zloop_t* loop, zsock_t* reader, void* arg) {
} break;
case SCTP_DATA_CNF:
+ is_state_same = true; // the following handler does not modify state
s1ap_mme_itti_nas_downlink_cnf(
SCTP_DATA_CNF(received_message_p).agw_ue_xap_id,
SCTP_DATA_CNF(received_message_p).is_success);
@@ -174,15 +179,18 @@ static int handle_message(zloop_t* loop, zsock_t* reader, void* arg) {
s1ap_generate_downlink_nas_transport(
state, S1AP_NAS_DL_DATA_REQ(received_message_p).enb_ue_s1ap_id,
S1AP_NAS_DL_DATA_REQ(received_message_p).mme_ue_s1ap_id,
- &S1AP_NAS_DL_DATA_REQ(received_message_p).nas_msg, imsi64);
+ &S1AP_NAS_DL_DATA_REQ(received_message_p).nas_msg, imsi64,
+ &is_state_same);
} break;
case S1AP_E_RAB_SETUP_REQ: {
+ is_state_same = true; // the following handler does not modify state
s1ap_generate_s1ap_e_rab_setup_req(
state, &S1AP_E_RAB_SETUP_REQ(received_message_p));
} break;
case S1AP_E_RAB_MODIFICATION_CNF: {
+ is_state_same = true; // the following handler does not modify state
s1ap_mme_generate_erab_modification_confirm(
state, &received_message_p->ittiMsg.s1ap_e_rab_modification_cnf);
} break;
@@ -195,6 +203,7 @@ static int handle_message(zloop_t* loop, zsock_t* reader, void* arg) {
} break;
case MME_APP_CONNECTION_ESTABLISHMENT_CNF: {
+ is_state_same = true; // the following handler does not modify state
s1ap_handle_conn_est_cnf(
state, &MME_APP_CONNECTION_ESTABLISHMENT_CNF(received_message_p));
} break;
@@ -205,11 +214,13 @@ static int handle_message(zloop_t* loop, zsock_t* reader, void* arg) {
} break;
case S1AP_ENB_INITIATED_RESET_ACK: {
+ is_state_same = true; // the following handler does not modify state
s1ap_handle_enb_initiated_reset_ack(
&S1AP_ENB_INITIATED_RESET_ACK(received_message_p), imsi64);
} break;
case S1AP_PAGING_REQUEST: {
+ is_state_same = true; // the following handler does not modify state
if (s1ap_handle_paging_request(
state, &S1AP_PAGING_REQUEST(received_message_p), imsi64) !=
RETURNok) {
@@ -218,23 +229,27 @@ static int handle_message(zloop_t* loop, zsock_t* reader, void* arg) {
} break;
case S1AP_UE_CONTEXT_MODIFICATION_REQUEST: {
+ is_state_same = true; // the following handler does not modify state
s1ap_handle_ue_context_mod_req(
state, &received_message_p->ittiMsg.s1ap_ue_context_mod_request,
imsi64);
} break;
case S1AP_E_RAB_REL_CMD: {
+ is_state_same = true; // the following handler does not modify state
s1ap_generate_s1ap_e_rab_rel_cmd(
state, &S1AP_E_RAB_REL_CMD(received_message_p));
} break;
case S1AP_PATH_SWITCH_REQUEST_ACK: {
+ is_state_same = true; // the following handler does not modify state
s1ap_handle_path_switch_req_ack(
state, &received_message_p->ittiMsg.s1ap_path_switch_request_ack,
imsi64);
} break;
case S1AP_PATH_SWITCH_REQUEST_FAILURE: {
+ is_state_same = true; // the following handler does not modify state
s1ap_handle_path_switch_req_failure(
state, &received_message_p->ittiMsg.s1ap_path_switch_request_failure,
imsi64);
@@ -298,9 +313,11 @@ static int handle_message(zloop_t* loop, zsock_t* reader, void* arg) {
} break;
}
- put_s1ap_state();
- put_s1ap_imsi_map();
- put_s1ap_ue_state(imsi64);
+ if (!is_state_same) {
+ put_s1ap_state();
+ put_s1ap_imsi_map();
+ put_s1ap_ue_state(imsi64);
+ }
itti_free_msg_content(received_message_p);
free(received_message_p);
return 0;
diff --git a/lte/gateway/c/oai/tasks/s1ap/s1ap_mme_handlers.c b/lte/gateway/c/oai/tasks/s1ap/s1ap_mme_handlers.c
index d9aca03b216a..5a9a69839fa5 100644
--- a/lte/gateway/c/oai/tasks/s1ap/s1ap_mme_handlers.c
+++ b/lte/gateway/c/oai/tasks/s1ap/s1ap_mme_handlers.c
@@ -362,13 +362,20 @@ void clean_stale_enb_state(
ue_description_t* ue_ref = NULL;
for (int i = 0; i < keys->num_keys; i++) {
ue_ref = s1ap_state_get_ue_mmeid((mme_ue_s1ap_id_t) keys->keys[i]);
+ /* The function s1ap_remove_ue will take care of removing the enb also,
+ * when the last UE is removed
+ */
s1ap_remove_ue(state, ue_ref);
}
FREE_HASHTABLE_KEY_ARRAY(keys);
+ } else {
+ // Remove the old eNB association
+ OAILOG_INFO(
+ LOG_S1AP, "Deleting eNB: %s (Sctp_assoc_id = %u)",
+ stale_enb_association->enb_name, stale_enb_association->sctp_assoc_id);
+ s1ap_remove_enb(state, stale_enb_association);
}
- // Remove the old eNB association
- s1ap_remove_enb(state, stale_enb_association);
OAILOG_DEBUG(LOG_S1AP, "Removed stale eNB and all associated UEs.");
}
@@ -1036,8 +1043,6 @@ int s1ap_mme_handle_ue_context_release_request(
S1ap_UEContextReleaseRequest_t* container;
S1ap_UEContextReleaseRequest_IEs_t* ie = NULL;
ue_description_t* ue_ref_p = NULL;
- enb_description_t* enb_ref_p = NULL;
- MessageDef* message_p = NULL;
S1ap_Cause_PR cause_type;
long cause_value;
enum s1cause s1_release_cause = S1AP_RADIO_EUTRAN_GENERATED_REASON;
@@ -1180,23 +1185,9 @@ int s1ap_mme_handle_ue_context_release_request(
hashtable_uint64_ts_get(
imsi_map->mme_ue_id_imsi_htbl, (const hash_key_t) mme_ue_s1ap_id,
&imsi64);
+ rc = s1ap_send_mme_ue_context_release(
+ state, ue_ref_p, s1_release_cause, ie->value.choice.Cause, imsi64);
- message_p =
- itti_alloc_new_message(TASK_S1AP, S1AP_UE_CONTEXT_RELEASE_REQ);
- AssertFatal(message_p != NULL, "itti_alloc_new_message Failed");
-
- enb_ref_p = s1ap_state_get_enb(state, ue_ref_p->sctp_assoc_id);
-
- S1AP_UE_CONTEXT_RELEASE_REQ(message_p).mme_ue_s1ap_id =
- ue_ref_p->mme_ue_s1ap_id;
- S1AP_UE_CONTEXT_RELEASE_REQ(message_p).enb_ue_s1ap_id =
- ue_ref_p->enb_ue_s1ap_id;
- S1AP_UE_CONTEXT_RELEASE_REQ(message_p).enb_id = enb_ref_p->enb_id;
- S1AP_UE_CONTEXT_RELEASE_REQ(message_p).relCause = s1_release_cause;
- S1AP_UE_CONTEXT_RELEASE_REQ(message_p).cause = ie->value.choice.Cause;
-
- message_p->ittiMsgHeader.imsi = imsi64;
- rc = send_msg_to_task(&s1ap_task_zmq_ctx, TASK_MME_APP, message_p);
OAILOG_FUNC_RETURN(LOG_S1AP, rc);
} else {
// abnormal case. No need to do anything. Ignore the message
@@ -1823,10 +1814,12 @@ int s1ap_mme_handle_ue_context_modification_failure(
S1AP_FIND_PROTOCOLIE_BY_ID(
S1ap_UEContextModificationFailureIEs_t, ie, container,
S1ap_ProtocolIE_ID_id_Cause, true);
- if (!ie) {
+ if (ie) {
+ cause_type = ie->value.choice.Cause.present;
+ } else {
OAILOG_FUNC_RETURN(LOG_S1AP, RETURNerror);
}
- cause_value = ie->value.choice.Cause.choice.radioNetwork;
+
switch (cause_type) {
case S1ap_Cause_PR_radioNetwork:
cause_value = ie->value.choice.Cause.choice.radioNetwork;
@@ -2525,9 +2518,117 @@ int s1ap_mme_handle_error_ind_message(
s1ap_state_t* state, const sctp_assoc_id_t assoc_id,
const sctp_stream_id_t stream, S1ap_S1AP_PDU_t* message) {
OAILOG_FUNC_IN(LOG_S1AP);
- OAILOG_WARNING(
- LOG_S1AP, "ERROR IND RCVD on Stream id %d, ignoring it\n", stream);
+ OAILOG_WARNING(LOG_S1AP, "ERROR IND RCVD on Stream id %d \n", stream);
increment_counter("s1ap_error_ind_rcvd", 1, NO_LABELS);
+ S1ap_ErrorIndication_t* container = NULL;
+ S1ap_ErrorIndicationIEs_t* ie = NULL;
+ ue_description_t* ue_ref_p = NULL;
+ enb_ue_s1ap_id_t enb_ue_s1ap_id = INVALID_ENB_UE_S1AP_ID;
+ mme_ue_s1ap_id_t mme_ue_s1ap_id = INVALID_MME_UE_S1AP_ID;
+ S1ap_Cause_PR cause_type;
+ long cause_value;
+
+ container = &message->choice.initiatingMessage.value.choice.ErrorIndication;
+ S1AP_FIND_PROTOCOLIE_BY_ID(
+ S1ap_ErrorIndicationIEs_t, ie, container,
+ S1ap_ProtocolIE_ID_id_MME_UE_S1AP_ID, true);
+ if (ie) {
+ mme_ue_s1ap_id = ie->value.choice.MME_UE_S1AP_ID;
+ } else {
+ OAILOG_FUNC_RETURN(LOG_S1AP, RETURNerror);
+ }
+
+ S1AP_FIND_PROTOCOLIE_BY_ID(
+ S1ap_ErrorIndicationIEs_t, ie, container,
+ S1ap_ProtocolIE_ID_id_eNB_UE_S1AP_ID, true);
+ if (ie) {
+ // eNB UE S1AP ID is limited to 24 bits
+ enb_ue_s1ap_id = (enb_ue_s1ap_id_t)(
+ ie->value.choice.ENB_UE_S1AP_ID & ENB_UE_S1AP_ID_MASK);
+ } else {
+ OAILOG_FUNC_RETURN(LOG_S1AP, RETURNerror);
+ }
+
+ S1AP_FIND_PROTOCOLIE_BY_ID(
+ S1ap_ErrorIndicationIEs_t, ie, container, S1ap_ProtocolIE_ID_id_Cause,
+ true);
+ if (ie) {
+ cause_type = ie->value.choice.Cause.present;
+ } else {
+ OAILOG_FUNC_RETURN(LOG_S1AP, RETURNerror);
+ }
+
+ if ((ue_ref_p = s1ap_state_get_ue_mmeid((uint32_t) mme_ue_s1ap_id)) == NULL) {
+ OAILOG_WARNING(
+ LOG_S1AP,
+ "No UE is attached to this mme UE s1ap id: " MME_UE_S1AP_ID_FMT
+ " and eNB UE s1ap id: \n" ENB_UE_S1AP_ID_FMT,
+ mme_ue_s1ap_id, enb_ue_s1ap_id);
+ OAILOG_FUNC_RETURN(LOG_S1AP, RETURNerror);
+ }
+
+ imsi64_t imsi64 = INVALID_IMSI64;
+ s1ap_imsi_map_t* imsi_map = get_s1ap_imsi_map();
+ hashtable_uint64_ts_get(
+ imsi_map->mme_ue_id_imsi_htbl, (const hash_key_t) mme_ue_s1ap_id,
+ &imsi64);
+
+ switch (cause_type) {
+ case S1ap_Cause_PR_radioNetwork:
+ cause_value = ie->value.choice.Cause.choice.radioNetwork;
+ OAILOG_DEBUG_UE(
+ LOG_S1AP, imsi64,
+ "Error Indication with Cause_Type = Radio Network "
+ "and Cause_Value = %ld\n",
+ cause_value);
+ s1ap_send_mme_ue_context_release(
+ state, ue_ref_p, S1AP_RADIO_EUTRAN_GENERATED_REASON,
+ ie->value.choice.Cause, imsi64);
+ break;
+
+ case S1ap_Cause_PR_transport:
+ cause_value = ie->value.choice.Cause.choice.transport;
+ OAILOG_DEBUG_UE(
+ LOG_S1AP, imsi64,
+ "Error Indication with Cause_Type = Transport and "
+ "Cause_Value = %ld\n",
+ cause_value);
+ break;
+
+ case S1ap_Cause_PR_nas:
+ cause_value = ie->value.choice.Cause.choice.nas;
+ OAILOG_DEBUG_UE(
+ LOG_S1AP, imsi64,
+ "Error Indication with Cause_Type = NAS and "
+ "Cause_Value = %ld\n",
+ cause_value);
+ break;
+
+ case S1ap_Cause_PR_protocol:
+ cause_value = ie->value.choice.Cause.choice.protocol;
+ OAILOG_DEBUG_UE(
+ LOG_S1AP, imsi64,
+ "Error Indication with Cause_Type = Protocol and "
+ "Cause_Value = %ld\n",
+ cause_value);
+ break;
+
+ case S1ap_Cause_PR_misc:
+ cause_value = ie->value.choice.Cause.choice.misc;
+ OAILOG_DEBUG_UE(
+ LOG_S1AP, imsi64,
+ "Error Indication with Cause_Type = MISC and "
+ "Cause_Value = %ld\n",
+ cause_value);
+ break;
+
+ default:
+ OAILOG_ERROR_UE(
+ LOG_S1AP, imsi64, "Error Indication with Invalid Cause_Type = %d\n",
+ cause_type);
+ OAILOG_FUNC_RETURN(LOG_S1AP, RETURNerror);
+ }
+
OAILOG_FUNC_RETURN(LOG_S1AP, RETURNok);
}
@@ -3892,3 +3993,30 @@ int s1ap_mme_remove_stale_ue_context(
send_msg_to_task(&s1ap_task_zmq_ctx, TASK_MME_APP, message_p);
OAILOG_FUNC_RETURN(LOG_S1AP, RETURNok);
}
+
+int s1ap_send_mme_ue_context_release(
+ s1ap_state_t* state, ue_description_t* ue_ref_p,
+ enum s1cause s1_release_cause, S1ap_Cause_t ie_cause, imsi64_t imsi64) {
+ MessageDef* message_p = NULL;
+ message_p = itti_alloc_new_message(TASK_S1AP, S1AP_UE_CONTEXT_RELEASE_REQ);
+ if (!message_p) {
+ OAILOG_ERROR(
+ LOG_S1AP,
+ "Failed to allocate memory for S1AP_REMOVE_STALE_UE_CONTEXT \n");
+ OAILOG_FUNC_RETURN(LOG_S1AP, RETURNerror);
+ }
+
+ enb_description_t* enb_ref_p =
+ s1ap_state_get_enb(state, ue_ref_p->sctp_assoc_id);
+
+ S1AP_UE_CONTEXT_RELEASE_REQ(message_p).mme_ue_s1ap_id =
+ ue_ref_p->mme_ue_s1ap_id;
+ S1AP_UE_CONTEXT_RELEASE_REQ(message_p).enb_ue_s1ap_id =
+ ue_ref_p->enb_ue_s1ap_id;
+ S1AP_UE_CONTEXT_RELEASE_REQ(message_p).enb_id = enb_ref_p->enb_id;
+ S1AP_UE_CONTEXT_RELEASE_REQ(message_p).relCause = s1_release_cause;
+ S1AP_UE_CONTEXT_RELEASE_REQ(message_p).cause = ie_cause;
+
+ message_p->ittiMsgHeader.imsi = imsi64;
+ return send_msg_to_task(&s1ap_task_zmq_ctx, TASK_MME_APP, message_p);
+}
diff --git a/lte/gateway/c/oai/tasks/s1ap/s1ap_mme_handlers.h b/lte/gateway/c/oai/tasks/s1ap/s1ap_mme_handlers.h
index b42e2c8e565d..2520f36e8395 100644
--- a/lte/gateway/c/oai/tasks/s1ap/s1ap_mme_handlers.h
+++ b/lte/gateway/c/oai/tasks/s1ap/s1ap_mme_handlers.h
@@ -173,4 +173,8 @@ int s1ap_mme_generate_ue_context_release_command(
int s1ap_mme_remove_stale_ue_context(
enb_ue_s1ap_id_t enb_ue_s1ap_id, uint32_t enb_id);
+
+int s1ap_send_mme_ue_context_release(
+ s1ap_state_t* state, ue_description_t* ue_ref_p,
+ enum s1cause s1_release_cause, S1ap_Cause_t ie_cause, imsi64_t imsi64);
#endif /* FILE_S1AP_MME_HANDLERS_SEEN */
diff --git a/lte/gateway/c/oai/tasks/s1ap/s1ap_mme_itti_messaging.c b/lte/gateway/c/oai/tasks/s1ap/s1ap_mme_itti_messaging.c
index 3c4c4658dfa1..590eebbc47e8 100644
--- a/lte/gateway/c/oai/tasks/s1ap/s1ap_mme_itti_messaging.c
+++ b/lte/gateway/c/oai/tasks/s1ap/s1ap_mme_itti_messaging.c
@@ -106,11 +106,11 @@ int s1ap_mme_itti_nas_downlink_cnf(
if (!is_success) {
OAILOG_ERROR(
LOG_S1AP,
- "ERROR: Failed to send connection less S1AP message to eNB. "
+ "ERROR: Failed to send connectionless S1AP message to eNB. "
"mme_ue_s1ap_id = %d \n",
ue_id);
}
- // Drop this cnf message here since this is related to connection less S1AP
+ // Drop this cnf message here since this is related to connectionless S1AP
// message hence no need to send it to NAS module
OAILOG_FUNC_RETURN(LOG_S1AP, RETURNok);
}
diff --git a/lte/gateway/c/oai/tasks/s1ap/s1ap_mme_nas_procedures.c b/lte/gateway/c/oai/tasks/s1ap/s1ap_mme_nas_procedures.c
index 4e3d35de67a2..e8d3745a9c25 100644
--- a/lte/gateway/c/oai/tasks/s1ap/s1ap_mme_nas_procedures.c
+++ b/lte/gateway/c/oai/tasks/s1ap/s1ap_mme_nas_procedures.c
@@ -471,7 +471,7 @@ int s1ap_mme_handle_nas_non_delivery(
int s1ap_generate_downlink_nas_transport(
s1ap_state_t* state, const enb_ue_s1ap_id_t enb_ue_s1ap_id,
const mme_ue_s1ap_id_t ue_id, STOLEN_REF bstring* payload,
- const imsi64_t imsi64) {
+ const imsi64_t imsi64, bool* is_state_same) {
ue_description_t* ue_ref = NULL;
uint8_t* buffer_p = NULL;
uint32_t length = 0;
@@ -480,7 +480,7 @@ int s1ap_generate_downlink_nas_transport(
OAILOG_FUNC_IN(LOG_S1AP);
- // Try to retrieve SCTP assoication id using mme_ue_s1ap_id
+ // Try to retrieve SCTP association id using mme_ue_s1ap_id
if (HASH_TABLE_OK ==
hashtable_ts_get(
&state->mmeid2associd, (const hash_key_t) ue_id, (void**) &id)) {
@@ -513,12 +513,15 @@ int s1ap_generate_downlink_nas_transport(
OAILOG_FUNC_RETURN(LOG_S1AP, RETURNerror);
} else {
/*
- * We have fount the UE in the list.
+ * We have found the UE in the list.
* * * * Create new IE list message and encode it.
*/
s1ap_imsi_map_t* imsi_map = get_s1ap_imsi_map();
- hashtable_uint64_ts_insert(
- imsi_map->mme_ue_id_imsi_htbl, (const hash_key_t) ue_id, imsi64);
+ if (hashtable_uint64_ts_insert(
+ imsi_map->mme_ue_id_imsi_htbl, (const hash_key_t) ue_id, imsi64) ==
+ HASH_TABLE_SAME_KEY_VALUE_EXISTS) {
+ *is_state_same = true;
+ }
S1ap_DownlinkNASTransport_IEs_t* ie = NULL;
S1ap_DownlinkNASTransport_t* out = NULL;
@@ -536,7 +539,7 @@ int s1ap_generate_downlink_nas_transport(
if (ue_ref->s1_ue_state == S1AP_UE_WAITING_CRR) {
OAILOG_ERROR_UE(
LOG_S1AP, imsi64,
- "Already triggred UE Context Release Command and UE is"
+ "Already triggered UE Context Release Command and UE is"
"in S1AP_UE_WAITING_CRR, so dropping the DownlinkNASTransport \n");
OAILOG_FUNC_RETURN(LOG_S1AP, RETURNerror);
} else {
diff --git a/lte/gateway/c/oai/tasks/s1ap/s1ap_mme_nas_procedures.h b/lte/gateway/c/oai/tasks/s1ap/s1ap_mme_nas_procedures.h
index 2f5cc6c258a5..d9d8cf30fa41 100644
--- a/lte/gateway/c/oai/tasks/s1ap/s1ap_mme_nas_procedures.h
+++ b/lte/gateway/c/oai/tasks/s1ap/s1ap_mme_nas_procedures.h
@@ -70,7 +70,8 @@ void s1ap_handle_conn_est_cnf(
int s1ap_generate_downlink_nas_transport(
s1ap_state_t* state, const enb_ue_s1ap_id_t enb_ue_s1ap_id,
- const mme_ue_s1ap_id_t ue_id, STOLEN_REF bstring* payload, imsi64_t imsi64);
+ const mme_ue_s1ap_id_t ue_id, STOLEN_REF bstring* payload, imsi64_t imsi64,
+ bool* is_state_same);
void s1ap_handle_mme_ue_id_notification(
s1ap_state_t* state,
diff --git a/lte/gateway/c/oai/tasks/s1ap/s1ap_state_manager.cpp b/lte/gateway/c/oai/tasks/s1ap/s1ap_state_manager.cpp
index 6cec1082f896..3cf0a24a1a56 100644
--- a/lte/gateway/c/oai/tasks/s1ap/s1ap_state_manager.cpp
+++ b/lte/gateway/c/oai/tasks/s1ap/s1ap_state_manager.cpp
@@ -28,7 +28,11 @@ using magma::lte::oai::UeDescription;
namespace magma {
namespace lte {
-S1apStateManager::S1apStateManager() : max_ues_(0), max_enbs_(0) {}
+S1apStateManager::S1apStateManager()
+ : max_ues_(0),
+ max_enbs_(0),
+ s1ap_imsi_map_hash_(0),
+ s1ap_imsi_map_(nullptr) {}
S1apStateManager::~S1apStateManager() {
free_state();
@@ -194,7 +198,15 @@ void S1apStateManager::write_s1ap_imsi_map_to_db() {
}
oai::S1apImsiMap imsi_proto = oai::S1apImsiMap();
S1apStateConverter::s1ap_imsi_map_to_proto(s1ap_imsi_map_, &imsi_proto);
- redis_client->write_proto(S1AP_IMSI_MAP_TABLE_NAME, imsi_proto);
+ std::string proto_msg;
+ redis_client->serialize(imsi_proto, proto_msg);
+ std::size_t new_hash = std::hash{}(proto_msg);
+
+ // s1ap_imsi_map is not state service synced, so version will not be updated
+ if (new_hash != this->s1ap_imsi_map_hash_) {
+ redis_client->write_proto_str(S1AP_IMSI_MAP_TABLE_NAME, proto_msg, 0);
+ this->s1ap_imsi_map_hash_ = new_hash;
+ }
}
} // namespace lte
diff --git a/lte/gateway/c/oai/tasks/s1ap/s1ap_state_manager.h b/lte/gateway/c/oai/tasks/s1ap/s1ap_state_manager.h
index 3abfc5e9c498..2ed0652797ac 100644
--- a/lte/gateway/c/oai/tasks/s1ap/s1ap_state_manager.h
+++ b/lte/gateway/c/oai/tasks/s1ap/s1ap_state_manager.h
@@ -89,7 +89,7 @@ class S1apStateManager
private:
S1apStateManager();
- ~S1apStateManager();
+ ~S1apStateManager() override;
/**
* Allocates new s1ap_state_t struct and its properties
@@ -102,6 +102,7 @@ class S1apStateManager
uint32_t max_ues_;
uint32_t max_enbs_;
s1ap_imsi_map_t* s1ap_imsi_map_;
+ std::size_t s1ap_imsi_map_hash_;
};
} // namespace lte
} // namespace magma
diff --git a/lte/gateway/c/oai/tasks/sgw/sgw_context_manager.c b/lte/gateway/c/oai/tasks/sgw/sgw_context_manager.c
index 518d53c49439..49ae8700d9ac 100644
--- a/lte/gateway/c/oai/tasks/sgw/sgw_context_manager.c
+++ b/lte/gateway/c/oai/tasks/sgw/sgw_context_manager.c
@@ -65,41 +65,41 @@ void sgw_display_sgw_eps_bearer_context(
//-----------------------------------------------------------------------------
void sgw_display_s11_bearer_context_information(
+ log_proto_t module,
sgw_eps_bearer_context_information_t* sgw_context_information)
//-----------------------------------------------------------------------------
{
OAILOG_DEBUG(
- LOG_SPGW_APP, "| KEY %" PRId64 ": \n",
- sgw_context_information->imsi64);
- OAILOG_DEBUG(LOG_SPGW_APP, "|\tsgw_eps_bearer_context_information: |\n");
+ module, "| KEY %" PRId64 ": \n", sgw_context_information->imsi64);
+ OAILOG_DEBUG(module, "|\tsgw_eps_bearer_context_information: |\n");
// Imsi_t imsi; ///< IMSI
// (International Mobile Subscriber Identity) is the subscriber permanent
// identity.
OAILOG_DEBUG(
- LOG_SPGW_APP, "|\t\timsi_unauthenticated_indicator:\t%u\n",
+ module, "|\t\timsi_unauthenticated_indicator:\t%u\n",
sgw_context_information->imsi_unauthenticated_indicator);
// char msisdn[MSISDN_LENGTH]; ///< The basic MSISDN
// of the UE. The presence is dictated by its storage in the HSS.
OAILOG_DEBUG(
- LOG_SPGW_APP, "|\t\tmme_teid_ S11: \t" TEID_FMT "\n",
+ module, "|\t\tmme_teid_ S11: \t" TEID_FMT "\n",
sgw_context_information->mme_teid_S11);
// ip_address_t mme_ip_address_for_S11; ///< MME IP address
// the S11 interface.
OAILOG_DEBUG(
- LOG_SPGW_APP, "|\t\ts_gw_teid_S11_S4: \t" TEID_FMT "\n",
+ module, "|\t\ts_gw_teid_S11_S4: \t" TEID_FMT "\n",
sgw_context_information->s_gw_teid_S11_S4);
// ip_address_t s_gw_ip_address_for_S11_S4; ///< S-GW IP address
// for the S11 interface and the S4 Interface (control plane). cgi_t
// last_known_cell_Id; ///< This is the last location of the UE
// known by the network
- OAILOG_DEBUG(LOG_SPGW_APP, "|\t\tpdn_connection:\n");
+ OAILOG_DEBUG(module, "|\t\tpdn_connection:\n");
OAILOG_DEBUG(
- LOG_SPGW_APP, "|\t\t\tapn_in_use: %s\n",
+ module, "|\t\t\tapn_in_use: %s\n",
sgw_context_information->pdn_connection.apn_in_use);
OAILOG_DEBUG(
- LOG_SPGW_APP, "|\t\t\tdefault_bearer: %u\n",
+ module, "|\t\t\tdefault_bearer: %u\n",
sgw_context_information->pdn_connection.default_bearer);
- OAILOG_DEBUG(LOG_SPGW_APP, "|\t\t\teps_bearers:\n");
+ OAILOG_DEBUG(module, "|\t\t\teps_bearers:\n");
for (int ebix = 0; ebix < BEARERS_PER_UE; ebix++) {
sgw_display_sgw_eps_bearer_context(
sgw_context_information->pdn_connection.sgw_eps_bearers_array[ebix]);
diff --git a/lte/gateway/c/oai/tasks/sgw/sgw_handlers.c b/lte/gateway/c/oai/tasks/sgw/sgw_handlers.c
index 49dd3bb4410c..84aa1e6d25e3 100644
--- a/lte/gateway/c/oai/tasks/sgw/sgw_handlers.c
+++ b/lte/gateway/c/oai/tasks/sgw/sgw_handlers.c
@@ -78,9 +78,6 @@ static void generate_dl_flow(
packet_filter_contents_t* packet_filter, in_addr_t ipv4_s_addr,
struct in6_addr* ue_ipv6, struct ip_flow_dl* dlflow);
-static bool does_bearer_context_hold_valid_enb_ip(
- ip_address_t enb_ip_address_S1u);
-
static void add_tunnel_helper(
s_plus_p_gw_eps_bearer_context_information_t* spgw_context,
sgw_eps_bearer_ctxt_t* eps_bearer_ctxt_entry_p, imsi64_t imsi64);
@@ -255,8 +252,8 @@ int sgw_handle_s11_create_session_request(
session_req_pP->bearer_contexts_to_be_created.bearer_contexts[0]
.eps_bearer_id);
sgw_display_s11_bearer_context_information(
- &s_plus_p_gw_eps_bearer_ctxt_info_p
- ->sgw_eps_bearer_context_information);
+ LOG_SPGW_APP, &s_plus_p_gw_eps_bearer_ctxt_info_p
+ ->sgw_eps_bearer_context_information);
if (eps_bearer_ctxt_p == NULL) {
OAILOG_ERROR_UE(
@@ -439,10 +436,11 @@ int sgw_handle_sgi_endpoint_created(
/* Populates bearer contexts marked for removal structure in
* modify bearer rsp message.
*/
-static void sgw_populate_mbr_bearer_contexts_not_found(
+void sgw_populate_mbr_bearer_contexts_not_found(
+ log_proto_t module,
const itti_sgi_update_end_point_response_t* const resp_pP,
itti_s11_modify_bearer_response_t* modify_response_p) {
- OAILOG_FUNC_IN(LOG_SPGW_APP);
+ OAILOG_FUNC_IN(module);
uint8_t rsp_idx = 0;
for (uint8_t idx = 0; idx < resp_pP->num_bearers_not_found; idx++) {
modify_response_p->bearer_contexts_marked_for_removal
@@ -453,23 +451,22 @@ static void sgw_populate_mbr_bearer_contexts_not_found(
.cause.cause_value = CONTEXT_NOT_FOUND;
modify_response_p->bearer_contexts_marked_for_removal.num_bearer_context++;
}
- OAILOG_FUNC_OUT(LOG_SPGW_APP);
+ OAILOG_FUNC_OUT(module);
}
//------------------------------------------------------------------------------
/* Populates bearer contexts marked for removal structure in
* modify bearer rsp message
*/
-static void sgw_populate_mbr_bearer_contexts_removed(
+void sgw_populate_mbr_bearer_contexts_removed(
const itti_sgi_update_end_point_response_t* const resp_pP, imsi64_t imsi64,
- s_plus_p_gw_eps_bearer_context_information_t* new_bearer_ctxt_info_p,
+ sgw_eps_bearer_context_information_t* sgw_context_p,
itti_s11_modify_bearer_response_t* modify_response_p) {
OAILOG_FUNC_IN(LOG_SPGW_APP);
uint8_t rsp_idx = 0;
sgw_eps_bearer_ctxt_t* eps_bearer_ctxt_p = NULL;
for (uint8_t idx = 0; idx < resp_pP->num_bearers_removed; idx++) {
eps_bearer_ctxt_p = sgw_cm_get_eps_bearer_entry(
- &new_bearer_ctxt_info_p->sgw_eps_bearer_context_information
- .pdn_connection,
+ &(sgw_context_p->pdn_connection),
resp_pP->bearer_contexts_to_be_removed[idx]);
/* If context is found, delete the context and set cause as
* REQUEST_ACCEPTED. If context is not found set the cause as
@@ -478,9 +475,8 @@ static void sgw_populate_mbr_bearer_contexts_removed(
*/
if (NULL != eps_bearer_ctxt_p) {
sgw_free_eps_bearer_context(
- &new_bearer_ctxt_info_p->sgw_eps_bearer_context_information
- .pdn_connection.sgw_eps_bearers_array[EBI_TO_INDEX(
- eps_bearer_ctxt_p->eps_bearer_id)]);
+ &(sgw_context_p->pdn_connection.sgw_eps_bearers_array[EBI_TO_INDEX(
+ eps_bearer_ctxt_p->eps_bearer_id)]));
modify_response_p->bearer_contexts_marked_for_removal
.bearer_contexts[rsp_idx]
.cause.cause_value = REQUEST_ACCEPTED;
@@ -672,8 +668,8 @@ void sgw_handle_sgi_endpoint_updated(
OAILOG_DEBUG_UE(
LOG_SPGW_APP, imsi64,
- "Rx SGI_UPDATE_ENDPOINT_RESPONSE, Context teid " TEID_FMT " status %d\n",
- resp_pP->context_teid, resp_pP->status);
+ "Rx SGI_UPDATE_ENDPOINT_RESPONSE, Context teid " TEID_FMT "\n",
+ resp_pP->context_teid);
message_p = itti_alloc_new_message(TASK_SPGW_APP, S11_MODIFY_BEARER_RESPONSE);
if (!message_p) {
@@ -698,8 +694,11 @@ void sgw_handle_sgi_endpoint_updated(
sgw_populate_mbr_bearer_contexts_modified(
resp_pP, imsi64, new_bearer_ctxt_info_p, modify_response_p);
sgw_populate_mbr_bearer_contexts_removed(
- resp_pP, imsi64, new_bearer_ctxt_info_p, modify_response_p);
- sgw_populate_mbr_bearer_contexts_not_found(resp_pP, modify_response_p);
+ resp_pP, imsi64,
+ &new_bearer_ctxt_info_p->sgw_eps_bearer_context_information,
+ modify_response_p);
+ sgw_populate_mbr_bearer_contexts_not_found(
+ LOG_SPGW_APP, resp_pP, modify_response_p);
send_msg_to_task(&spgw_app_task_zmq_ctx, TASK_MME, message_p);
}
OAILOG_FUNC_OUT(LOG_SPGW_APP);
@@ -860,7 +859,7 @@ int sgw_handle_sgi_endpoint_deleted(
//------------------------------------------------------------------------------
// This function populates itti_sgi_update_end_point_response_t message
-static void populate_sgi_end_point_update(
+void populate_sgi_end_point_update(
uint8_t sgi_rsp_idx, uint8_t idx,
const itti_s11_modify_bearer_request_t* const modify_bearer_pP,
sgw_eps_bearer_ctxt_t* eps_bearer_ctxt_p,
@@ -887,18 +886,19 @@ static void populate_sgi_end_point_update(
//------------------------------------------------------------------------------
// This function populates and sends MBR failure message to MME APP
-static int send_mbr_failure(
+int send_mbr_failure(
+ log_proto_t module,
const itti_s11_modify_bearer_request_t* const modify_bearer_pP,
imsi64_t imsi64) {
int rv = RETURNok;
- OAILOG_FUNC_IN(LOG_SPGW_APP);
+ OAILOG_FUNC_IN(module);
MessageDef* message_p =
itti_alloc_new_message(TASK_SPGW_APP, S11_MODIFY_BEARER_RESPONSE);
if (!message_p) {
OAILOG_ERROR(
- LOG_SPGW_APP, "S11_MODIFY_BEARER_RESPONSE memory allocation failed\n");
- OAILOG_FUNC_RETURN(LOG_SPGW_APP, RETURNerror);
+ module, "S11_MODIFY_BEARER_RESPONSE memory allocation failed\n");
+ OAILOG_FUNC_RETURN(module, RETURNerror);
}
itti_s11_modify_bearer_response_t* modify_response_p =
@@ -921,13 +921,13 @@ static int send_mbr_failure(
modify_response_p->cause.cause_value = CONTEXT_NOT_FOUND;
modify_response_p->trxn = modify_bearer_pP->trxn;
OAILOG_DEBUG_UE(
- LOG_SPGW_APP, imsi64,
+ module, imsi64,
"Rx MODIFY_BEARER_REQUEST, teid " TEID_FMT " CONTEXT_NOT_FOUND\n",
modify_bearer_pP->teid);
message_p->ittiMsgHeader.imsi = imsi64;
rv = send_msg_to_task(&spgw_app_task_zmq_ctx, TASK_MME, message_p);
- OAILOG_FUNC_RETURN(LOG_SPGW_APP, rv);
+ OAILOG_FUNC_RETURN(module, rv);
}
//------------------------------------------------------------------------------
@@ -956,7 +956,6 @@ int sgw_handle_modify_bearer_request(
modify_bearer_pP->trxn;
sgi_update_end_point_resp.context_teid = modify_bearer_pP->teid;
- sgi_update_end_point_resp.status = 0;
uint8_t sgi_rsp_idx = 0;
for (idx = 0;
idx <
@@ -1031,7 +1030,7 @@ int sgw_handle_modify_bearer_request(
}
sgw_handle_sgi_endpoint_updated(&sgi_update_end_point_resp, imsi64);
} else { // bearer_ctxt_info_p not found
- rv = send_mbr_failure(modify_bearer_pP, imsi64);
+ rv = send_mbr_failure(LOG_SPGW_APP, modify_bearer_pP, imsi64);
if (rv != RETURNok) {
OAILOG_ERROR(
LOG_SPGW_APP,
@@ -2227,8 +2226,7 @@ static void add_tunnel_helper(
}
}
}
-static bool does_bearer_context_hold_valid_enb_ip(
- ip_address_t enb_ip_address_S1u) {
+bool does_bearer_context_hold_valid_enb_ip(ip_address_t enb_ip_address_S1u) {
OAILOG_FUNC_IN(LOG_SPGW_APP);
static struct in6_addr ipv6_address = {0};
switch (enb_ip_address_S1u.pdn_type) {
diff --git a/lte/gateway/c/oai/tasks/sgw/sgw_handlers.h b/lte/gateway/c/oai/tasks/sgw/sgw_handlers.h
index 21f40af3d490..658164070882 100644
--- a/lte/gateway/c/oai/tasks/sgw/sgw_handlers.h
+++ b/lte/gateway/c/oai/tasks/sgw/sgw_handlers.h
@@ -69,4 +69,28 @@ int sgw_handle_ip_allocation_rsp(
const itti_ip_allocation_response_t* ip_allocation_rsp, imsi64_t imsi64);
bool is_enb_ip_address_same(const fteid_t* fte_p, ip_address_t* ip_p);
uint32_t spgw_get_new_s1u_teid(spgw_state_t* state);
+int send_mbr_failure(
+ log_proto_t module,
+ const itti_s11_modify_bearer_request_t* const modify_bearer_pP,
+ imsi64_t imsi64);
+void sgw_populate_mbr_bearer_contexts_removed(
+ const itti_sgi_update_end_point_response_t* const resp_pP, imsi64_t imsi64,
+ sgw_eps_bearer_context_information_t* sgw_context_p,
+ itti_s11_modify_bearer_response_t* modify_response_p);
+void sgw_populate_mbr_bearer_contexts_not_found(
+ log_proto_t module,
+ const itti_sgi_update_end_point_response_t* const resp_pP,
+ itti_s11_modify_bearer_response_t* modify_response_p);
+void populate_sgi_end_point_update(
+ uint8_t sgi_rsp_idx, uint8_t idx,
+ const itti_s11_modify_bearer_request_t* const modify_bearer_pP,
+ sgw_eps_bearer_ctxt_t* eps_bearer_ctxt_p,
+ itti_sgi_update_end_point_response_t* sgi_update_end_point_resp);
+bool does_bearer_context_hold_valid_enb_ip(ip_address_t enb_ip_address_S1u);
+void populate_sgi_end_point_update(
+ uint8_t sgi_rsp_idx, uint8_t idx,
+ const itti_s11_modify_bearer_request_t* const modify_bearer_pP,
+ sgw_eps_bearer_ctxt_t* eps_bearer_ctxt_p,
+ itti_sgi_update_end_point_response_t* sgi_update_end_point_resp);
+
#endif /* FILE_SGW_HANDLERS_SEEN */
diff --git a/lte/gateway/c/oai/tasks/sgw_s8/sgw_s8_handlers.c b/lte/gateway/c/oai/tasks/sgw_s8/sgw_s8_handlers.c
index 765a6d9a58ce..6a703020a3db 100644
--- a/lte/gateway/c/oai/tasks/sgw_s8/sgw_s8_handlers.c
+++ b/lte/gateway/c/oai/tasks/sgw_s8/sgw_s8_handlers.c
@@ -24,14 +24,24 @@ limitations under the License.
#include "s8_client_api.h"
#include "gtpv1u.h"
#include "dynamic_memory_check.h"
+#include "sgw_handlers.h"
extern task_zmq_ctx_t sgw_s8_task_zmq_ctx;
extern struct gtp_tunnel_ops* gtp_tunnel_ops;
-
-static int sgw_s8_add_gtp_tunnel(
+static int sgw_s8_add_gtp_up_tunnel(
sgw_eps_bearer_ctxt_t* eps_bearer_ctxt_p,
sgw_eps_bearer_context_information_t* sgw_context_p);
+static void sgw_send_modify_bearer_response(
+ sgw_eps_bearer_context_information_t* sgw_context_p,
+ const itti_sgi_update_end_point_response_t* const resp_pP, imsi64_t imsi64);
+
+static void sgw_s8_send_failed_delete_session_response(
+ sgw_eps_bearer_context_information_t* sgw_context_p,
+ gtpv2c_cause_value_t cause, sgw_state_t* sgw_state,
+ const itti_s11_delete_session_request_t* const delete_session_req_p,
+ imsi64_t imsi64);
+
uint32_t sgw_get_new_s1u_teid(sgw_state_t* state) {
if (state->s1u_teid == 0) {
state->s1u_teid = INITIAL_SGW_S8_S1U_TEID;
@@ -44,6 +54,10 @@ uint32_t sgw_get_new_s5s8u_teid(sgw_state_t* state) {
__sync_fetch_and_add(&state->s5s8u_teid, 1);
return (state->s5s8u_teid);
}
+static void sgw_s8_populate_mbr_bearer_contexts_modified(
+ const itti_sgi_update_end_point_response_t* const resp_pP, imsi64_t imsi64,
+ sgw_eps_bearer_context_information_t* sgw_context_p,
+ itti_s11_modify_bearer_response_t* modify_response_p);
void sgw_remove_sgw_bearer_context_information(
sgw_state_t* sgw_state, teid_t teid, imsi64_t imsi64) {
@@ -254,7 +268,8 @@ void sgw_s8_handle_s11_create_session_request(
memcpy(
new_sgw_eps_context->imsi.digit, session_req_pP->imsi.digit,
IMSI_BCD_DIGITS_MAX);
- new_sgw_eps_context->imsi64 = imsi64;
+ new_sgw_eps_context->imsi.length = session_req_pP->imsi.length;
+ new_sgw_eps_context->imsi64 = imsi64;
new_sgw_eps_context->imsi_unauthenticated_indicator = 1;
new_sgw_eps_context->mme_teid_S11 = session_req_pP->sender_fteid_for_cp.teid;
@@ -300,7 +315,7 @@ void sgw_s8_handle_s11_create_session_request(
send_s8_create_session_request(
sgw_s11_tunnel.local_teid, session_req_pP, imsi64);
- sgw_display_s11_bearer_context_information(new_sgw_eps_context);
+ sgw_display_s11_bearer_context_information(LOG_SGW_S8, new_sgw_eps_context);
OAILOG_FUNC_OUT(LOG_SGW_S8);
}
@@ -338,7 +353,6 @@ static int update_bearer_context_info(
memcpy(
&default_bearer_ctx_p->eps_bearer_qos, &s5s8_bearer_context.qos,
sizeof(bearer_qos_t));
- sgw_s8_add_gtp_tunnel(default_bearer_ctx_p, sgw_context_p);
OAILOG_FUNC_RETURN(LOG_SGW_S8, RETURNok);
}
@@ -490,18 +504,220 @@ void sgw_s8_handle_create_session_response(
OAILOG_FUNC_OUT(LOG_SGW_S8);
}
+void sgw_s8_handle_modify_bearer_request(
+ sgw_state_t* state,
+ const itti_s11_modify_bearer_request_t* const modify_bearer_pP,
+ imsi64_t imsi64) {
+ OAILOG_FUNC_IN(LOG_SGW_S8);
+
+ uint8_t idx = 0;
+ uint8_t sgi_rsp_idx = 0;
+ itti_sgi_update_end_point_response_t sgi_update_end_point_resp = {0};
+ struct in_addr enb = {.s_addr = 0};
+ struct in_addr pgw = {.s_addr = 0};
+ sgw_eps_bearer_ctxt_t* bearer_ctx_p = NULL;
+
+ OAILOG_INFO_UE(
+ LOG_SGW_S8, imsi64, "Rx MODIFY_BEARER_REQUEST, teid " TEID_FMT "\n",
+ modify_bearer_pP->teid);
+
+ sgw_eps_bearer_context_information_t* sgw_context_p =
+ sgw_get_sgw_eps_bearer_context(modify_bearer_pP->teid);
+ if (!sgw_context_p) {
+ OAILOG_ERROR_UE(
+ LOG_SGW_S8, imsi64,
+ "Failed to fetch sgw_eps_bearer_context_info from "
+ "context_teid " TEID_FMT " \n",
+ modify_bearer_pP->teid);
+ if ((send_mbr_failure(LOG_SGW_S8, modify_bearer_pP, imsi64) != RETURNok)) {
+ OAILOG_ERROR(
+ LOG_SGW_S8,
+ "Error in sending modify bearer response to MME App for context "
+ "teid " TEID_FMT "\n",
+ modify_bearer_pP->teid);
+ }
+ OAILOG_FUNC_OUT(LOG_SGW_S8);
+ }
+ sgw_context_p->trxn = modify_bearer_pP->trxn;
+ sgi_update_end_point_resp.context_teid = modify_bearer_pP->teid;
+ // Traversing through the list of bearers to be modified
+ for (; idx <
+ modify_bearer_pP->bearer_contexts_to_be_modified.num_bearer_context;
+ idx++) {
+ bearer_context_to_be_modified_t mbr_bearer_ctxt_p =
+ modify_bearer_pP->bearer_contexts_to_be_modified.bearer_contexts[idx];
+ bearer_ctx_p = sgw_cm_get_eps_bearer_entry(
+ &sgw_context_p->pdn_connection, mbr_bearer_ctxt_p.eps_bearer_id);
+ if (!bearer_ctx_p) {
+ OAILOG_ERROR_UE(
+ LOG_SGW_S8, imsi64,
+ "Failed to get eps bearer context for context teid " TEID_FMT
+ "and bearer_id :%u \n",
+ modify_bearer_pP->teid, mbr_bearer_ctxt_p.eps_bearer_id);
+ sgi_update_end_point_resp.bearer_contexts_not_found[sgi_rsp_idx++] =
+ mbr_bearer_ctxt_p.eps_bearer_id;
+ sgi_update_end_point_resp.num_bearers_not_found++;
+ } else {
+ enb.s_addr = bearer_ctx_p->enb_ip_address_S1u.address.ipv4_address.s_addr;
+ pgw.s_addr =
+ bearer_ctx_p->p_gw_address_in_use_up.address.ipv4_address.s_addr;
+
+ // Send end marker to eNB and then delete the tunnel if enb_ip is
+ // different
+ if (does_bearer_context_hold_valid_enb_ip(
+ bearer_ctx_p->enb_ip_address_S1u) &&
+ is_enb_ip_address_same(
+ &mbr_bearer_ctxt_p.s1_eNB_fteid,
+ &bearer_ctx_p->enb_ip_address_S1u) == false) {
+ struct in_addr ue_ipv4 = bearer_ctx_p->paa.ipv4_address;
+ struct in6_addr* ue_ipv6 = NULL;
+ if ((bearer_ctx_p->paa.pdn_type == IPv6) ||
+ (bearer_ctx_p->paa.pdn_type == IPv4_AND_v6)) {
+ ue_ipv6 = &bearer_ctx_p->paa.ipv6_address;
+ }
+
+ OAILOG_DEBUG_UE(
+ LOG_SGW_S8, imsi64,
+ "Delete GTPv1-U tunnel for sgw_teid:" TEID_FMT "for bearer %u\n",
+ bearer_ctx_p->s_gw_teid_S1u_S12_S4_up, bearer_ctx_p->eps_bearer_id);
+ // This is best effort, ignore return code.
+ gtp_tunnel_ops->send_end_marker(enb, modify_bearer_pP->teid);
+ // delete GTPv1-U tunnel
+ gtpv1u_del_s8_tunnel(
+ enb, pgw, ue_ipv4, ue_ipv6, bearer_ctx_p->s_gw_teid_S1u_S12_S4_up,
+ bearer_ctx_p->enb_teid_S1u, NULL);
+ }
+ populate_sgi_end_point_update(
+ sgi_rsp_idx, idx, modify_bearer_pP, bearer_ctx_p,
+ &sgi_update_end_point_resp);
+ sgi_rsp_idx++;
+ }
+ } // for loop
+
+ sgi_rsp_idx = 0;
+ for (idx = 0;
+ idx < modify_bearer_pP->bearer_contexts_to_be_removed.num_bearer_context;
+ idx++) {
+ bearer_ctx_p = sgw_cm_get_eps_bearer_entry(
+ &sgw_context_p->pdn_connection,
+ modify_bearer_pP->bearer_contexts_to_be_removed.bearer_contexts[idx]
+ .eps_bearer_id);
+ if (bearer_ctx_p) {
+ sgi_update_end_point_resp.bearer_contexts_to_be_removed[sgi_rsp_idx++] =
+ bearer_ctx_p->eps_bearer_id;
+ sgi_update_end_point_resp.num_bearers_removed++;
+ }
+ }
+ sgw_send_modify_bearer_response(
+ sgw_context_p, &sgi_update_end_point_resp, imsi64);
+ OAILOG_FUNC_OUT(LOG_SGW_S8);
+}
+
+static void sgw_send_modify_bearer_response(
+ sgw_eps_bearer_context_information_t* sgw_context_p,
+ const itti_sgi_update_end_point_response_t* const resp_pP,
+ imsi64_t imsi64) {
+ OAILOG_FUNC_IN(LOG_SGW_S8);
+ itti_s11_modify_bearer_response_t* modify_response_p = NULL;
+ MessageDef* message_p = NULL;
+
+ OAILOG_DEBUG_UE(
+ LOG_SGW_S8, imsi64,
+ "send modify bearer response for Context teid " TEID_FMT "\n",
+ resp_pP->context_teid);
+ message_p = itti_alloc_new_message(TASK_SGW_S8, S11_MODIFY_BEARER_RESPONSE);
+
+ if (!message_p) {
+ OAILOG_ERROR_UE(
+ LOG_SGW_S8, imsi64,
+ "Failed to allocate memory for S11_MODIFY_BEARER_RESPONSE\n");
+ OAILOG_FUNC_OUT(LOG_SGW_S8);
+ }
+
+ modify_response_p = &message_p->ittiMsg.s11_modify_bearer_response;
+
+ if (sgw_context_p) {
+ modify_response_p->teid = sgw_context_p->mme_teid_S11;
+ modify_response_p->cause.cause_value = REQUEST_ACCEPTED;
+ modify_response_p->trxn = sgw_context_p->trxn;
+ message_p->ittiMsgHeader.imsi = imsi64;
+
+ sgw_s8_populate_mbr_bearer_contexts_modified(
+ resp_pP, imsi64, sgw_context_p, modify_response_p);
+ sgw_populate_mbr_bearer_contexts_removed(
+ resp_pP, imsi64, sgw_context_p, modify_response_p);
+ sgw_populate_mbr_bearer_contexts_not_found(
+ LOG_SGW_S8, resp_pP, modify_response_p);
+ send_msg_to_task(&sgw_s8_task_zmq_ctx, TASK_MME_APP, message_p);
+ }
+ OAILOG_FUNC_OUT(LOG_SGW_S8);
+}
+
+static void sgw_s8_populate_mbr_bearer_contexts_modified(
+ const itti_sgi_update_end_point_response_t* const resp_pP, imsi64_t imsi64,
+ sgw_eps_bearer_context_information_t* sgw_context_p,
+ itti_s11_modify_bearer_response_t* modify_response_p) {
+ OAILOG_FUNC_IN(LOG_SGW_S8);
+ uint8_t rsp_idx = 0;
+ sgw_eps_bearer_ctxt_t* eps_bearer_ctxt_p = NULL;
+
+ for (uint8_t idx = 0; idx < resp_pP->num_bearers_modified; idx++) {
+ eps_bearer_ctxt_p = sgw_cm_get_eps_bearer_entry(
+ &sgw_context_p->pdn_connection,
+ resp_pP->bearer_contexts_to_be_modified[idx].eps_bearer_id);
+
+ if (NULL != eps_bearer_ctxt_p) {
+ OAILOG_DEBUG_UE(
+ LOG_SGW_S8, imsi64,
+ "Modify bearer request is accepted for bearer_id :%u\n",
+ resp_pP->bearer_contexts_to_be_modified[idx].eps_bearer_id);
+ modify_response_p->bearer_contexts_modified.bearer_contexts[rsp_idx]
+ .eps_bearer_id =
+ resp_pP->bearer_contexts_to_be_modified[idx].eps_bearer_id;
+ modify_response_p->bearer_contexts_modified.bearer_contexts[rsp_idx++]
+ .cause.cause_value = REQUEST_ACCEPTED;
+ modify_response_p->bearer_contexts_modified.num_bearer_context++;
+
+ // setup GTPv1-U tunnels, both s1-u and s8-u tunnels
+ sgw_s8_add_gtp_up_tunnel(eps_bearer_ctxt_p, sgw_context_p);
+ // may be removed TODO rashmi remove after testing
+ if (TRAFFIC_FLOW_TEMPLATE_NB_PACKET_FILTERS_MAX >
+ eps_bearer_ctxt_p->num_sdf) {
+ int i = 0;
+ while ((i < eps_bearer_ctxt_p->num_sdf) &&
+ (SDF_ID_NGBR_DEFAULT != eps_bearer_ctxt_p->sdf_id[i]))
+ i++;
+ if (i >= eps_bearer_ctxt_p->num_sdf) {
+ eps_bearer_ctxt_p->sdf_id[eps_bearer_ctxt_p->num_sdf] =
+ SDF_ID_NGBR_DEFAULT;
+ eps_bearer_ctxt_p->num_sdf += 1;
+ }
+ }
+ }
+ }
+ OAILOG_FUNC_OUT(LOG_SGW_S8);
+}
+
// Helper function to add gtp tunnels for default bearers
-static int sgw_s8_add_gtp_tunnel(
+static int sgw_s8_add_gtp_up_tunnel(
sgw_eps_bearer_ctxt_t* eps_bearer_ctxt_p,
sgw_eps_bearer_context_information_t* sgw_context_p) {
int rv = RETURNok;
struct in_addr enb = {.s_addr = 0};
struct in_addr pgw = {.s_addr = 0};
+ pgw.s_addr =
+ eps_bearer_ctxt_p->p_gw_address_in_use_up.address.ipv4_address.s_addr;
+ if ((pgw.s_addr == 0) && (eps_bearer_ctxt_p->p_gw_teid_S5_S8_up == 0)) {
+ OAILOG_ERROR_UE(
+ LOG_SGW_S8, sgw_context_p->imsi64,
+ "bearer context has invalid pgw_s8_teid " TEID_FMT
+ "pgw_ip address :%x \n",
+ eps_bearer_ctxt_p->p_gw_teid_S5_S8_up, pgw.s_addr);
+ OAILOG_FUNC_RETURN(LOG_SGW_S8, RETURNerror);
+ }
enb.s_addr =
eps_bearer_ctxt_p->enb_ip_address_S1u.address.ipv4_address.s_addr;
- pgw.s_addr =
- eps_bearer_ctxt_p->p_gw_address_in_use_up.address.ipv4_address.s_addr;
struct in_addr ue_ipv4 = {.s_addr = 0};
struct in6_addr* ue_ipv6 = NULL;
ue_ipv4.s_addr = eps_bearer_ctxt_p->paa.ipv4_address.s_addr;
@@ -517,47 +733,298 @@ static int sgw_s8_add_gtp_tunnel(
if (ue_ipv6) {
inet_ntop(AF_INET6, ue_ipv6, ip6_str, INET6_ADDRSTRLEN);
}
- /* UE is switching back to EPS services after the CS Fallback
- * If Modify bearer Request is received in UE suspended mode, Resume PS
- * data
- */
- if (sgw_context_p->pdn_connection.ue_suspended_for_ps_handover) {
- rv = gtp_tunnel_ops->forward_data_on_tunnel(
- ue_ipv4, ue_ipv6, eps_bearer_ctxt_p->s_gw_teid_S1u_S12_S4_up, NULL,
- DEFAULT_PRECEDENCE);
+ OAILOG_DEBUG_UE(
+ LOG_SGW_S8, sgw_context_p->imsi64,
+ "Adding tunnel for bearer_id %u ue addr %x enb %x "
+ "s_gw_teid_S1u_S12_S4_up %x, enb_teid_S1u %x pgw_up_ip %x pgw_up_teid %x "
+ "s_gw_ip_address_S5_S8_up %x"
+ "s_gw_teid_S5_S8_up %x \n ",
+ eps_bearer_ctxt_p->eps_bearer_id, ue_ipv4.s_addr, enb.s_addr,
+ eps_bearer_ctxt_p->s_gw_teid_S1u_S12_S4_up,
+ eps_bearer_ctxt_p->enb_teid_S1u, pgw.s_addr,
+ eps_bearer_ctxt_p->p_gw_teid_S5_S8_up,
+ eps_bearer_ctxt_p->s_gw_ip_address_S5_S8_up.address.ipv4_address.s_addr,
+ eps_bearer_ctxt_p->s_gw_teid_S5_S8_up);
+ if (eps_bearer_ctxt_p->eps_bearer_id ==
+ sgw_context_p->pdn_connection.default_bearer) {
+ // Set default precedence and tft for default bearer
+ if (ue_ipv6) {
+ OAILOG_INFO_UE(
+ LOG_SGW_S8, sgw_context_p->imsi64,
+ "Adding tunnel for ipv6 ue addr %s, enb %x, "
+ "s_gw_teid_S5_S8_up %x, s_gw_ip_address_S5_S8_up %x pgw_up_ip %x "
+ "pgw_up_teid %x \n",
+ ip6_str, enb.s_addr, eps_bearer_ctxt_p->s_gw_teid_S5_S8_up,
+ eps_bearer_ctxt_p->s_gw_ip_address_S5_S8_up.address.ipv4_address
+ .s_addr,
+ pgw.s_addr, eps_bearer_ctxt_p->p_gw_teid_S5_S8_up);
+ }
+ rv = gtpv1u_add_s8_tunnel(
+ ue_ipv4, ue_ipv6, vlan, enb, pgw,
+ eps_bearer_ctxt_p->s_gw_teid_S1u_S12_S4_up,
+ eps_bearer_ctxt_p->enb_teid_S1u, eps_bearer_ctxt_p->s_gw_teid_S5_S8_up,
+ eps_bearer_ctxt_p->p_gw_teid_S5_S8_up, imsi, NULL, DEFAULT_PRECEDENCE);
if (rv < 0) {
OAILOG_ERROR_UE(
LOG_SGW_S8, sgw_context_p->imsi64,
- "ERROR in forwarding data on TUNNEL err=%d\n", rv);
+ "ERROR in setting up TUNNEL err=%d\n", rv);
}
- } else {
+ }
+ OAILOG_FUNC_RETURN(LOG_SGW_S8, rv);
+}
+
+void sgw_s8_handle_s11_delete_session_request(
+ sgw_state_t* sgw_state,
+ const itti_s11_delete_session_request_t* const delete_session_req_p,
+ imsi64_t imsi64) {
+ OAILOG_FUNC_IN(LOG_SGW_S8);
+ gtpv2c_cause_value_t gtpv2c_cause = 0;
+ if (!delete_session_req_p) {
+ OAILOG_ERROR_UE(
+ LOG_SGW_S8, imsi64,
+ "Received NULL delete_session_req_p from mme app \n");
+ OAILOG_FUNC_OUT(LOG_SGW_S8);
+ }
+ OAILOG_INFO_UE(
+ LOG_SGW_S8, imsi64,
+ "Received S11 DELETE SESSION REQUEST for sgw_s11_teid " TEID_FMT "\n",
+ delete_session_req_p->teid);
+ increment_counter("sgw_delete_session", 1, NO_LABELS);
+ if (delete_session_req_p->indication_flags.oi) {
OAILOG_DEBUG_UE(
- LOG_SGW_S8, sgw_context_p->imsi64,
- "Adding tunnel for bearer %u ue addr %x\n",
- eps_bearer_ctxt_p->eps_bearer_id, ue_ipv4.s_addr);
- if (eps_bearer_ctxt_p->eps_bearer_id ==
- sgw_context_p->pdn_connection.default_bearer) {
- // Set default precedence and tft for default bearer
- if (ue_ipv6) {
- OAILOG_INFO_UE(
- LOG_SGW_S8, sgw_context_p->imsi64,
- "Adding tunnel for ipv6 ue addr %s, enb %x, "
- "s_gw_teid_S1u_S12_S4_up %x, enb_teid_S1u %x pgw_up_ip %x "
- "pgw_up_teid %x \n",
- ip6_str, enb.s_addr, eps_bearer_ctxt_p->s_gw_teid_S1u_S12_S4_up,
- eps_bearer_ctxt_p->enb_teid_S1u, pgw.s_addr,
- eps_bearer_ctxt_p->p_gw_teid_S5_S8_up);
+ LOG_SPGW_APP, imsi64,
+ "OI flag is set for this message indicating the request"
+ "should be forwarded to P-GW entity\n");
+ }
+
+ sgw_eps_bearer_context_information_t* sgw_context_p =
+ sgw_get_sgw_eps_bearer_context(delete_session_req_p->teid);
+ if (!sgw_context_p) {
+ OAILOG_ERROR_UE(
+ LOG_SGW_S8, imsi64,
+ "Failed to fetch sgw_eps_bearer_context_info from "
+ "sgw_s11_teid " TEID_FMT " \n",
+ delete_session_req_p->teid);
+ gtpv2c_cause = CONTEXT_NOT_FOUND;
+ sgw_s8_send_failed_delete_session_response(
+ sgw_context_p, gtpv2c_cause, sgw_state, delete_session_req_p, imsi64);
+ OAILOG_FUNC_OUT(LOG_SGW_S8);
+ }
+ if ((delete_session_req_p->sender_fteid_for_cp.ipv4) &&
+ (delete_session_req_p->sender_fteid_for_cp.ipv6)) {
+ // Sender F-TEID IE present
+ if (delete_session_req_p->teid != sgw_context_p->mme_teid_S11) {
+ OAILOG_ERROR_UE(
+ LOG_SPGW_APP, imsi64,
+ "Mismatch in MME Teid for CP teid recevied in delete session "
+ "req: " TEID_FMT " teid present in sgw_context :" TEID_FMT "\n",
+ delete_session_req_p->teid, sgw_context_p->mme_teid_S11);
+ gtpv2c_cause = INVALID_PEER;
+ sgw_s8_send_failed_delete_session_response(
+ sgw_context_p, gtpv2c_cause, sgw_state, delete_session_req_p, imsi64);
+ OAILOG_FUNC_OUT(LOG_SGW_S8);
+ }
+ }
+ if (delete_session_req_p->lbi !=
+ sgw_context_p->pdn_connection.default_bearer) {
+ OAILOG_ERROR_UE(
+ LOG_SPGW_APP, imsi64,
+ "Mismatch in default eps bearer_id, bearer_id recevied in delete "
+ "session req :%d and bearer_id present in sgw_context :%d \n",
+ delete_session_req_p->lbi,
+ sgw_context_p->pdn_connection.default_bearer);
+ sgw_s8_send_failed_delete_session_response(
+ sgw_context_p, gtpv2c_cause, sgw_state, delete_session_req_p, imsi64);
+ OAILOG_FUNC_OUT(LOG_SGW_S8);
+ }
+
+ send_s8_delete_session_request(
+ sgw_context_p->imsi64, sgw_context_p->imsi,
+ sgw_context_p->s_gw_teid_S11_S4,
+ sgw_context_p->pdn_connection.p_gw_teid_S5_S8_cp,
+ sgw_context_p->pdn_connection.default_bearer);
+ OAILOG_FUNC_OUT(LOG_SGW_S8);
+}
+
+static void delete_userplane_tunnels(
+ sgw_eps_bearer_context_information_t* sgw_context_p) {
+ OAILOG_FUNC_IN(LOG_SGW_S8);
+ struct in_addr enb = {.s_addr = 0};
+ struct in_addr pgw = {.s_addr = 0};
+ sgw_eps_bearer_ctxt_t* bearer_ctxt_p = NULL;
+ int rv = RETURNerror;
+
+ for (int ebix = 0; ebix < BEARERS_PER_UE; ebix++) {
+ ebi_t ebi = INDEX_TO_EBI(ebix);
+ bearer_ctxt_p =
+ sgw_cm_get_eps_bearer_entry(&sgw_context_p->pdn_connection, ebi);
+
+ if (bearer_ctxt_p) {
+ enb.s_addr =
+ bearer_ctxt_p->enb_ip_address_S1u.address.ipv4_address.s_addr;
+ pgw.s_addr =
+ bearer_ctxt_p->p_gw_address_in_use_up.address.ipv4_address.s_addr;
+ struct in6_addr* ue_ipv6 = NULL;
+ if ((bearer_ctxt_p->paa.pdn_type == IPv6) ||
+ (bearer_ctxt_p->paa.pdn_type == IPv4_AND_v6)) {
+ ue_ipv6 = &bearer_ctxt_p->paa.ipv6_address;
}
- rv = gtpv1u_add_s8_tunnel(
- ue_ipv4, ue_ipv6, vlan, enb, pgw,
- eps_bearer_ctxt_p->s_gw_teid_S1u_S12_S4_up,
- eps_bearer_ctxt_p->enb_teid_S1u, imsi, NULL, DEFAULT_PRECEDENCE);
+ // Delete S1-U tunnel
+ rv = openflow_del_s8_tunnel(
+ enb, pgw, bearer_ctxt_p->paa.ipv4_address, ue_ipv6,
+ bearer_ctxt_p->s_gw_teid_S1u_S12_S4_up, bearer_ctxt_p->enb_teid_S1u,
+ NULL);
if (rv < 0) {
OAILOG_ERROR_UE(
- LOG_SGW_S8, sgw_context_p->imsi64,
- "ERROR in setting up TUNNEL err=%d\n", rv);
+ LOG_SPGW_APP, sgw_context_p->imsi64,
+ "ERROR in deleting S1-U TUNNEL " TEID_FMT
+ " (eNB) <-> (SGW) " TEID_FMT "\n",
+ bearer_ctxt_p->enb_teid_S1u,
+ bearer_ctxt_p->s_gw_teid_S1u_S12_S4_up);
+ }
+ // Delete S8-U tunnel
+ rv = openflow_del_s8_tunnel(
+ enb, pgw, bearer_ctxt_p->paa.ipv4_address, ue_ipv6,
+ bearer_ctxt_p->s_gw_teid_S5_S8_up, bearer_ctxt_p->p_gw_teid_S5_S8_up,
+ NULL);
+ if (rv < 0) {
+ OAILOG_ERROR_UE(
+ LOG_SPGW_APP, sgw_context_p->imsi64,
+ "ERROR in deleting S8-U TUNNEL " TEID_FMT
+ " (PGW) <-> (SGW) " TEID_FMT "\n",
+ bearer_ctxt_p->p_gw_teid_S5_S8_up,
+ bearer_ctxt_p->s_gw_teid_S5_S8_up);
}
}
}
- OAILOG_FUNC_RETURN(LOG_SGW_S8, rv);
+ OAILOG_FUNC_OUT(LOG_SGW_S8);
+}
+
+void sgw_s8_handle_delete_session_response(
+ sgw_state_t* sgw_state, s8_delete_session_response_t* session_rsp_p,
+ imsi64_t imsi64) {
+ OAILOG_FUNC_IN(LOG_SGW_S8);
+ MessageDef* message_p = NULL;
+ itti_s11_delete_session_response_t* delete_session_response_p = NULL;
+
+ if (!session_rsp_p) {
+ OAILOG_ERROR_UE(
+ LOG_SGW_S8, imsi64,
+ "Received null delete session response from s8_proxy\n");
+ OAILOG_FUNC_OUT(LOG_SGW_S8);
+ }
+ OAILOG_INFO_UE(
+ LOG_SGW_S8, imsi64,
+ " Rx S5S8_DELETE_SESSION_RSP from s8_proxy for context_teid " TEID_FMT
+ "\n",
+ session_rsp_p->context_teid);
+
+ sgw_eps_bearer_context_information_t* sgw_context_p =
+ sgw_get_sgw_eps_bearer_context(session_rsp_p->context_teid);
+ if (!sgw_context_p) {
+ OAILOG_ERROR_UE(
+ LOG_SGW_S8, imsi64,
+ "Failed to fetch sgw_eps_bearer_context_info from "
+ "context_teid " TEID_FMT " \n",
+ session_rsp_p->context_teid);
+ OAILOG_FUNC_OUT(LOG_SGW_S8);
+ }
+ message_p = itti_alloc_new_message(TASK_SGW_S8, S11_DELETE_SESSION_RESPONSE);
+ if (message_p == NULL) {
+ OAILOG_CRITICAL_UE(
+ LOG_SGW_S8, sgw_context_p->imsi64,
+ "Failed to allocate memory for S11_delete_session_response for "
+ "context_teid " TEID_FMT "\n",
+ session_rsp_p->context_teid);
+ OAILOG_FUNC_OUT(LOG_SGW_S8);
+ }
+
+ delete_session_response_p = &message_p->ittiMsg.s11_delete_session_response;
+ message_p->ittiMsgHeader.imsi = imsi64;
+ if (!delete_session_response_p) {
+ OAILOG_ERROR_UE(
+ LOG_SGW_S8, sgw_context_p->imsi64,
+ "delete_session_response_p is NULL \n");
+ OAILOG_FUNC_OUT(LOG_SGW_S8);
+ }
+ delete_session_response_p->teid = sgw_context_p->mme_teid_S11;
+ delete_session_response_p->cause.cause_value = session_rsp_p->cause;
+ delete_session_response_p->trxn = sgw_context_p->trxn;
+ delete_session_response_p->lbi = sgw_context_p->pdn_connection.default_bearer;
+
+ // Delete ovs rules
+ delete_userplane_tunnels(sgw_context_p);
+ sgw_remove_sgw_bearer_context_information(
+ sgw_state, session_rsp_p->context_teid, imsi64);
+ // send delete session response to mme
+ if (send_msg_to_task(&sgw_s8_task_zmq_ctx, TASK_MME_APP, message_p) !=
+ RETURNok) {
+ OAILOG_ERROR_UE(
+ LOG_SGW_S8, imsi64,
+ "Failed to send delete session response to mme for "
+ "sgw_s11_teid " TEID_FMT "\n",
+ session_rsp_p->context_teid);
+ }
+ increment_counter("sgw_delete_session", 1, 1, "result", "success");
+ OAILOG_FUNC_OUT(LOG_SGW_S8);
+}
+
+static void sgw_s8_send_failed_delete_session_response(
+ sgw_eps_bearer_context_information_t* sgw_context_p,
+ gtpv2c_cause_value_t cause, sgw_state_t* sgw_state,
+ const itti_s11_delete_session_request_t* const delete_session_req_p,
+ imsi64_t imsi64) {
+ OAILOG_FUNC_IN(LOG_SGW_S8);
+ MessageDef* message_p = NULL;
+ itti_s11_delete_session_response_t* delete_session_response_p = NULL;
+ teid_t teid = 0;
+
+ message_p = itti_alloc_new_message(TASK_SGW_S8, S11_DELETE_SESSION_RESPONSE);
+ if (message_p == NULL) {
+ OAILOG_CRITICAL_UE(
+ LOG_SGW_S8, sgw_context_p->imsi64,
+ "Failed to allocate memory for S11_delete_session_response \n");
+ OAILOG_FUNC_OUT(LOG_SGW_S8);
+ }
+
+ delete_session_response_p = &message_p->ittiMsg.s11_delete_session_response;
+ message_p->ittiMsgHeader.imsi = imsi64;
+ if (!delete_session_response_p) {
+ OAILOG_ERROR_UE(
+ LOG_SGW_S8, sgw_context_p->imsi64,
+ "delete_session_response_p is NULL \n");
+ OAILOG_FUNC_OUT(LOG_SGW_S8);
+ }
+ if (sgw_context_p) {
+ delete_session_response_p->teid = sgw_context_p->mme_teid_S11;
+ delete_session_response_p->cause.cause_value = cause;
+ delete_session_response_p->trxn = sgw_context_p->trxn;
+ delete_session_response_p->lbi =
+ sgw_context_p->pdn_connection.default_bearer;
+
+ // Delete ovs rules
+ delete_userplane_tunnels(sgw_context_p);
+ sgw_remove_sgw_bearer_context_information(
+ sgw_state, sgw_context_p->s_gw_teid_S11_S4, imsi64);
+ teid = sgw_context_p->s_gw_teid_S11_S4;
+ } else {
+ if (delete_session_req_p) {
+ delete_session_response_p->teid = delete_session_req_p->local_teid;
+ delete_session_response_p->cause.cause_value = cause;
+ delete_session_response_p->trxn = delete_session_req_p->trxn;
+ delete_session_response_p->lbi = delete_session_req_p->lbi;
+ teid = delete_session_req_p->teid;
+ }
+ }
+ increment_counter("sgw_delete_session", 1, 1, "result", "failed");
+ // send delete session response to mme
+ if (send_msg_to_task(&sgw_s8_task_zmq_ctx, TASK_MME_APP, message_p) !=
+ RETURNok) {
+ OAILOG_ERROR_UE(
+ LOG_SGW_S8, imsi64,
+ "Failed to send delete session response to mme for "
+ "sgw_s11_teid " TEID_FMT "\n",
+ teid);
+ }
+ OAILOG_FUNC_OUT(LOG_SGW_S8);
}
diff --git a/lte/gateway/c/oai/tasks/sgw_s8/sgw_s8_s11_handlers.h b/lte/gateway/c/oai/tasks/sgw_s8/sgw_s8_s11_handlers.h
index 059f69b5064e..71659b15f910 100644
--- a/lte/gateway/c/oai/tasks/sgw_s8/sgw_s8_s11_handlers.h
+++ b/lte/gateway/c/oai/tasks/sgw_s8/sgw_s8_s11_handlers.h
@@ -24,3 +24,12 @@ void sgw_s8_handle_s11_create_session_request(
void sgw_s8_handle_create_session_response(
sgw_state_t* sgw_state, s8_create_session_response_t* session_rsp_p,
imsi64_t imsi64);
+
+void sgw_s8_handle_modify_bearer_request(
+ sgw_state_t* state,
+ const itti_s11_modify_bearer_request_t* const modify_bearer_pP,
+ imsi64_t imsi64);
+
+void sgw_s8_handle_delete_session_response(
+ sgw_state_t* sgw_state, s8_delete_session_response_t* session_rsp_p,
+ imsi64_t imsi64);
diff --git a/lte/gateway/c/oai/tasks/sgw_s8/sgw_s8_task.c b/lte/gateway/c/oai/tasks/sgw_s8/sgw_s8_task.c
index d48e6780b42b..4afac9be6bfa 100644
--- a/lte/gateway/c/oai/tasks/sgw_s8/sgw_s8_task.c
+++ b/lte/gateway/c/oai/tasks/sgw_s8/sgw_s8_task.c
@@ -76,7 +76,23 @@ static int handle_message(zloop_t* loop, zsock_t* reader, void* arg) {
sgw_state, &received_message_p->ittiMsg.s8_create_session_rsp,
imsi64);
} break;
+ case S11_MODIFY_BEARER_REQUEST: {
+ sgw_s8_handle_modify_bearer_request(
+ sgw_state, &received_message_p->ittiMsg.s11_modify_bearer_request,
+ imsi64);
+ } break;
+ case S11_DELETE_SESSION_REQUEST: {
+ sgw_s8_handle_s11_delete_session_request(
+ sgw_state, &received_message_p->ittiMsg.s11_delete_session_request,
+ imsi64);
+ } break;
+
+ case S8_DELETE_SESSION_RSP: {
+ sgw_s8_handle_delete_session_response(
+ sgw_state, &received_message_p->ittiMsg.s8_delete_session_rsp,
+ imsi64);
+ } break;
default: {
OAILOG_DEBUG(
LOG_SGW_S8, "Unkwnon message ID %d: %s\n",
diff --git a/lte/gateway/c/oai/test/openflow/test_gtp_app.cpp b/lte/gateway/c/oai/test/openflow/test_gtp_app.cpp
index 80657d5ae2ba..977c4bd66c9d 100644
--- a/lte/gateway/c/oai/test/openflow/test_gtp_app.cpp
+++ b/lte/gateway/c/oai/test/openflow/test_gtp_app.cpp
@@ -911,17 +911,20 @@ TEST_F(GTPApplicationTest, TestAddTunnelS8) {
struct in_addr enb_ip;
enb_ip.s_addr = inet_addr("0.0.0.2");
struct in_addr pgw_ip;
- enb_ip.s_addr = inet_addr("0.0.0.22");
- uint32_t in_tei = 1;
- uint32_t out_tei = 2;
- char imsi[] = "001010000000013";
- int vlan = 0;
- int enb_port = 100;
- int pgw_port = 200;
+ enb_ip.s_addr = inet_addr("0.0.0.22");
+ uint32_t in_tei = 1;
+ uint32_t out_tei = 2;
+ uint32_t pgw_in_tei = 3;
+ uint32_t pgw_out_tei = 4;
+
+ char imsi[] = "001010000000013";
+ int vlan = 0;
+ int enb_port = 100;
+ int pgw_port = 200;
AddGTPTunnelEvent add_tunnel(
- ue_ip, NULL, vlan, enb_ip, pgw_ip, in_tei, out_tei, imsi, enb_port,
- pgw_port);
+ ue_ip, NULL, vlan, enb_ip, pgw_ip, in_tei, out_tei, pgw_in_tei,
+ pgw_out_tei, imsi, enb_port, pgw_port);
// Uplink
EXPECT_CALL(
*messenger,
diff --git a/lte/gateway/c/session_manager/CMakeLists.txt b/lte/gateway/c/session_manager/CMakeLists.txt
index 0e79d1681e40..e2cf60714738 100644
--- a/lte/gateway/c/session_manager/CMakeLists.txt
+++ b/lte/gateway/c/session_manager/CMakeLists.txt
@@ -176,7 +176,19 @@ add_library(SESSION_MANAGER
${PROTO_SRCS}
${PROTO_HDRS})
-
+## Find + link sentry if it exists
+find_library(SENTRY_LIB NAMES sentry sentry-native)
+if (SENTRY_LIB)
+# Include dir
+message("Building with sentry!")
+find_path(SENTRY_INCLUDE_DIR
+ NAMES
+ sentry.h
+)
+target_link_libraries(SESSION_MANAGER ${SENTRY_LIB})
+set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSENTRY_ENABLED=1")
+set (CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DSENTRY_ENABLED=1")
+endif()
target_link_libraries(SESSION_MANAGER
SERVICE303_LIB SERVICE_REGISTRY ASYNC_GRPC CONFIG POLICYDB EVENTD
diff --git a/lte/gateway/c/session_manager/GrpcMagmaUtils.cpp b/lte/gateway/c/session_manager/GrpcMagmaUtils.cpp
index cede7be897f8..124271405e24 100644
--- a/lte/gateway/c/session_manager/GrpcMagmaUtils.cpp
+++ b/lte/gateway/c/session_manager/GrpcMagmaUtils.cpp
@@ -11,10 +11,14 @@
* limitations under the License.
*/
-#include
-#include "magma_logging.h"
-#include
#include "GrpcMagmaUtils.h"
+#include // for COMPACT_GOOGLE_LOG_INFO, Log...
+#include // for Descriptor
+#include // for Message
+#include // for getenv, NULL
+#include // for operator<<, basic_ostream
+#include // for string, operator<<, operator==
+#include "magma_logging.h" // for MINFO, MLOG
#define MAGMA_PRINT_GRPC_PAYLOAD "MAGMA_PRINT_GRPC_PAYLOAD"
diff --git a/lte/gateway/c/session_manager/GrpcMagmaUtils.h b/lte/gateway/c/session_manager/GrpcMagmaUtils.h
index ec576f96efe5..181c951cec30 100644
--- a/lte/gateway/c/session_manager/GrpcMagmaUtils.h
+++ b/lte/gateway/c/session_manager/GrpcMagmaUtils.h
@@ -12,7 +12,12 @@
*/
#pragma once
-#include "GRPCReceiver.h"
+#include // for string
+namespace google {
+namespace protobuf {
+class Message;
+}
+} // namespace google
std::string get_env_var(std::string const& key);
diff --git a/lte/gateway/c/session_manager/LocalEnforcer.cpp b/lte/gateway/c/session_manager/LocalEnforcer.cpp
index 5ea7c978651c..4964962d85d8 100644
--- a/lte/gateway/c/session_manager/LocalEnforcer.cpp
+++ b/lte/gateway/c/session_manager/LocalEnforcer.cpp
@@ -587,13 +587,20 @@ void LocalEnforcer::schedule_static_rule_activation(
<< "during installation of static rule " << rule_id;
return;
}
+ PolicyRule rule;
+ if (!rule_store_->get_rule(rule_id, &rule)) {
+ MLOG(MWARNING) << "Could not find static rules definition for "
+ << rule_id;
+ return;
+ }
+
auto& session = **session_it;
auto& uc = session_update[imsi][session_id];
std::time_t current_time = time(nullptr);
// don't install the rule if the current time is out of lifetime
- if (session->should_rule_be_active(rule_id, current_time)) {
- session->deactivate_scheduled_static_rule(rule_id, uc);
+ if (!session->should_rule_be_active(rule_id, current_time)) {
+ session->deactivate_scheduled_static_rule(rule_id);
session_store_.update_sessions(session_update);
return;
}
@@ -605,11 +612,10 @@ void LocalEnforcer::schedule_static_rule_activation(
const auto ambr = config.get_apn_ambr();
const std::string msisdn = config.common_context.msisdn();
- session->install_scheduled_static_rule(rule_id, uc);
- PolicyRule rule;
- rule_store_->get_rule(rule_id, &rule);
+ uint32_t version = session->activate_static_rule(
+ rule_id, session->get_rule_lifetime(rule_id), uc);
RulesToProcess to_process;
- to_process.rules = std::vector{rule};
+ to_process.append_versioned_policy(rule, version);
pipelined_client_->activate_flows_for_rules(
imsi, ip_addr, ipv6_addr, teids, msisdn, ambr, to_process,
@@ -647,7 +653,7 @@ void LocalEnforcer::schedule_dynamic_rule_activation(
}
// don't install the rule if the current time is out of lifetime
std::time_t current_time = time(nullptr);
- if (session->should_rule_be_active(rule_id, current_time)) {
+ if (!session->should_rule_be_active(rule_id, current_time)) {
session->remove_scheduled_dynamic_rule(rule_id, nullptr, session_uc);
session_store_.update_sessions(session_update);
return;
@@ -660,11 +666,17 @@ void LocalEnforcer::schedule_dynamic_rule_activation(
const auto ambr = config.get_apn_ambr();
const auto msisdn = config.common_context.msisdn();
- session->install_scheduled_dynamic_rule(rule_id, session_uc);
- PolicyRule policy;
- session->get_scheduled_dynamic_rules().get_rule(rule_id, &policy);
+ PolicyRule rule;
+ if (!session->remove_scheduled_dynamic_rule(
+ rule_id, &rule, session_uc)) {
+ MLOG(MWARNING) << "Dynamic rule " << rule_id << " doesn't exist for "
+ << session_id;
+ return;
+ }
+ uint32_t version = session->insert_dynamic_rule(
+ rule, session->get_rule_lifetime(rule_id), session_uc);
RulesToProcess to_process;
- to_process.rules = std::vector{policy};
+ to_process.append_versioned_policy(rule, version);
pipelined_client_->activate_flows_for_rules(
imsi, ip_addr, ipv6_addr, teids, msisdn, ambr, to_process,
@@ -691,8 +703,8 @@ void LocalEnforcer::schedule_static_rule_deactivation(
SessionSearchCriteria criteria(imsi, IMSI_AND_SESSION_ID, session_id);
auto session_it = session_store_.find_session(session_map, criteria);
if (!session_it) {
- MLOG(MWARNING) << "Could not find session " << session_id
- << "during removal of static rule " << rule_id;
+ MLOG(MERROR) << "Could not find session " << session_id
+ << "during removal of static rule " << rule_id;
return;
}
auto& session = **session_it;
@@ -708,17 +720,21 @@ void LocalEnforcer::schedule_static_rule_deactivation(
auto ip_addr = session->get_config().common_context.ue_ipv4();
auto ipv6_addr = session->get_config().common_context.ue_ipv6();
const Teids teids = session->get_config().common_context.teids();
- RulesToProcess to_process;
- to_process.rules = std::vector{rule};
+ auto& session_uc = session_update[imsi][session_id];
+ optional op_version =
+ session->deactivate_static_rule(rule_id, session_uc);
+ if (!op_version) {
+ MLOG(MERROR) << "Could not find rule " << rule_id << " for "
+ << session_id << " during static rule removal";
+ return;
+ }
+
+ RulesToProcess to_process;
+ to_process.append_versioned_policy(rule, *op_version);
pipelined_client_->deactivate_flows_for_rules(
imsi, ip_addr, ipv6_addr, teids, to_process, RequestOriginType::GX);
- auto& session_uc = session_update[imsi][session_id];
- if (!session->deactivate_static_rule(rule_id, session_uc)) {
- MLOG(MWARNING) << "Could not find rule " << rule_id << " for "
- << session_id << " during static rule removal";
- }
session_store_.update_sessions(session_update);
},
delta.count());
@@ -751,13 +767,16 @@ void LocalEnforcer::schedule_dynamic_rule_deactivation(
const Teids teids = session->get_config().common_context.teids();
PolicyRule policy;
- session->get_scheduled_dynamic_rules().get_rule(rule_id, &policy);
- RulesToProcess to_process;
- to_process.rules = std::vector{policy};
- pipelined_client_->deactivate_flows_for_rules(
- imsi, ip_addr, ipv6_addr, teids, to_process, RequestOriginType::GX);
auto& uc = session_update[imsi][session_id];
- session->remove_dynamic_rule(policy.id(), nullptr, uc);
+ optional op_version =
+ session->remove_dynamic_rule(policy.id(), &policy, uc);
+ if (op_version) {
+ RulesToProcess to_process;
+ to_process.append_versioned_policy(policy, *op_version);
+ pipelined_client_->deactivate_flows_for_rules(
+ imsi, ip_addr, ipv6_addr, teids, to_process,
+ RequestOriginType::GX);
+ }
session_store_.update_sessions(session_update);
},
delta.count());
@@ -1169,7 +1188,7 @@ void LocalEnforcer::remove_rules_for_suspended_credit(
// Remove pipelined rules
RulesToProcess rules_to_remove;
- session->get_rules_per_credit_key(ckey, rules_to_remove);
+ session->get_rules_per_credit_key(ckey, rules_to_remove, session_uc);
auto imsi = session->get_config().common_context.sid().id();
propagate_rule_updates_to_pipelined(
imsi, session->get_config(), RulesToProcess{}, rules_to_remove, false);
@@ -1208,7 +1227,7 @@ void LocalEnforcer::add_rules_for_unsuspended_credit(
// add pipelined rules
RulesToProcess rules_to_add;
- session->get_rules_per_credit_key(ckey, rules_to_add);
+ session->get_rules_per_credit_key(ckey, rules_to_add, session_uc);
auto imsi = session->get_config().common_context.sid().id();
propagate_rule_updates_to_pipelined(
imsi, session->get_config(), rules_to_add, RulesToProcess{}, false);
@@ -1644,19 +1663,36 @@ void LocalEnforcer::process_rules_to_remove(
rules_to_remove,
RulesToProcess& rules_to_deactivate, SessionStateUpdateCriteria& uc) {
for (const auto& rule_id : rules_to_remove) {
- // Try to remove as dynamic rule first
- PolicyRule dy_rule, st_rule;
- bool is_dynamic = session->remove_dynamic_rule(rule_id, &dy_rule, uc);
- if (is_dynamic) { // dynamic rule
- rules_to_deactivate.rules.push_back(dy_rule);
- } else if ( // static rule
- rule_store_->get_rule(rule_id, &st_rule) &&
- session->deactivate_static_rule(rule_id, uc)) {
- rules_to_deactivate.rules.push_back(st_rule);
- } else {
+ optional p_type = session->get_policy_type(rule_id);
+ if (!p_type) {
MLOG(MWARNING) << "Could not find rule " << rule_id << " for " << imsi
<< " during static rule removal";
+ continue;
+ }
+ optional op_version = {};
+ PolicyRule rule;
+ switch (*p_type) {
+ case DYNAMIC: {
+ op_version = session->remove_dynamic_rule(rule_id, &rule, uc);
+ break;
+ }
+ case STATIC: {
+ if (!rule_store_->get_rule(rule_id, &rule)) {
+ MLOG(MERROR) << "Static rule " << rule_id << " not found";
+ continue;
+ }
+ op_version = session->deactivate_static_rule(rule_id, uc);
+ break;
+ }
+ default:
+ break;
+ }
+ if (!op_version) {
+ MLOG(MERROR) << "Failed to remove " << rule_id << " for "
+ << session->get_session_id();
+ continue;
}
+ rules_to_deactivate.append_versioned_policy(rule, *op_version);
}
}
@@ -1701,6 +1737,7 @@ void LocalEnforcer::process_rules_to_install(
if (!rule_store_->get_rule(id, &static_rule)) {
MLOG(MERROR) << "static rule " << id
<< " is not found, skipping install...";
+ continue;
}
RuleLifetime lifetime(rule_install);
@@ -1709,9 +1746,9 @@ void LocalEnforcer::process_rules_to_install(
schedule_static_rule_activation(
imsi, session_id, id, lifetime.activation_time);
} else {
- session.activate_static_rule(id, lifetime, uc);
+ uint32_t version = session.activate_static_rule(id, lifetime, uc);
// Set up rules_to_activate
- rules_to_activate.rules.push_back(static_rule);
+ rules_to_activate.append_versioned_policy(static_rule, version);
}
if (lifetime.deactivation_time > current_time) {
@@ -1719,12 +1756,13 @@ void LocalEnforcer::process_rules_to_install(
imsi, session_id, id, lifetime.deactivation_time);
} else if (lifetime.deactivation_time > 0) {
// 0: never scheduled to deactivate
- if (!session.deactivate_static_rule(id, uc)) {
+ optional op_version = session.deactivate_static_rule(id, uc);
+ if (!op_version) {
MLOG(MWARNING) << "Could not find rule " << id << "for " << session_id
<< " during static rule removal";
+ } else {
+ rules_to_deactivate.append_versioned_policy(static_rule, *op_version);
}
-
- rules_to_deactivate.rules.push_back(static_rule);
}
}
@@ -1737,15 +1775,19 @@ void LocalEnforcer::process_rules_to_install(
schedule_dynamic_rule_activation(
imsi, session_id, rule_id, lifetime.activation_time);
} else {
- session.insert_dynamic_rule(dynamic_rule, lifetime, uc);
- rules_to_activate.rules.push_back(dynamic_rule);
+ uint32_t version =
+ session.insert_dynamic_rule(dynamic_rule, lifetime, uc);
+ rules_to_activate.append_versioned_policy(dynamic_rule, version);
}
if (lifetime.deactivation_time > current_time) {
schedule_dynamic_rule_deactivation(
imsi, session_id, rule_id, lifetime.deactivation_time);
} else if (lifetime.deactivation_time > 0) {
- session.remove_dynamic_rule(rule_id, nullptr, uc);
- rules_to_deactivate.rules.push_back(dynamic_rule);
+ optional op_version =
+ session.remove_dynamic_rule(rule_id, nullptr, uc);
+ if (op_version) {
+ rules_to_deactivate.append_versioned_policy(dynamic_rule, *op_version);
+ }
}
}
}
@@ -1995,22 +2037,23 @@ void LocalEnforcer::remove_rule_due_to_bearer_creation_failure(
}
PolicyRule rule;
- bool found = false;
+ optional op_version = {};
switch (*policy_type) {
case STATIC:
- session.deactivate_static_rule(rule_id, uc);
- found = rule_store_->get_rule(rule_id, &rule);
+ if (rule_store_->get_rule(rule_id, &rule)) {
+ op_version = session.deactivate_static_rule(rule_id, uc);
+ }
break;
case DYNAMIC: {
- found = session.remove_dynamic_rule(rule_id, &rule, uc);
+ op_version = session.remove_dynamic_rule(rule_id, &rule, uc);
break;
}
}
- if (found) {
+ if (op_version) {
auto config = session.get_config().common_context;
RulesToProcess to_process;
- to_process.rules = std::vector{rule};
+ to_process.append_versioned_policy(rule, *op_version);
pipelined_client_->deactivate_flows_for_rules(
imsi, config.ue_ipv4(), config.ue_ipv6(), config.teids(), to_process,
RequestOriginType::GX);
diff --git a/lte/gateway/c/session_manager/PipelinedClient.cpp b/lte/gateway/c/session_manager/PipelinedClient.cpp
index 4b63640744c0..4b813a03e099 100644
--- a/lte/gateway/c/session_manager/PipelinedClient.cpp
+++ b/lte/gateway/c/session_manager/PipelinedClient.cpp
@@ -62,9 +62,11 @@ magma::DeactivateFlowsRequest create_deactivate_req(
req.set_uplink_tunnel(teids.agw_teid());
req.set_remove_default_drop_flows(remove_default_drop_rules);
req.mutable_request_origin()->set_type(origin_type);
- auto ids = req.mutable_rule_ids();
- for (const auto& rule : to_process.rules) {
- ids->Add()->assign(rule.id());
+ auto mut_versioned_rules = req.mutable_policies();
+ for (uint index = 0; index < to_process.rules.size(); ++index) {
+ auto versioned_policy = mut_versioned_rules->Add();
+ versioned_policy->set_version(to_process.versions[index]);
+ versioned_policy->set_rule_id(to_process.rules[index].id());
}
return req;
}
@@ -87,9 +89,11 @@ magma::ActivateFlowsRequest create_activate_req(
if (ambr) {
req.mutable_apn_ambr()->CopyFrom(*ambr);
}
- auto mut_dyn_rules = req.mutable_dynamic_rules();
- for (const auto& dyn_rule : to_process.rules) {
- mut_dyn_rules->Add()->CopyFrom(dyn_rule);
+ auto mut_versioned_rules = req.mutable_policies();
+ for (uint index = 0; index < to_process.rules.size(); ++index) {
+ auto versioned_policy = mut_versioned_rules->Add();
+ versioned_policy->set_version(to_process.versions[index]);
+ versioned_policy->mutable_rule()->CopyFrom(to_process.rules[index]);
}
return req;
}
diff --git a/lte/gateway/c/session_manager/RedisStoreClient.cpp b/lte/gateway/c/session_manager/RedisStoreClient.cpp
index a4d7cc0ce036..96352073242b 100644
--- a/lte/gateway/c/session_manager/RedisStoreClient.cpp
+++ b/lte/gateway/c/session_manager/RedisStoreClient.cpp
@@ -11,9 +11,31 @@
* limitations under the License.
*/
-#include "SessionState.h"
#include "RedisStoreClient.h"
-#include "magma_logging.h"
+#include // for operator<<, StringPiece
+#include // for dynamic::dynamic, dynamic::~dyn...
+#include // for dynamic
+#include // for parseJson, toJson
+#include // for COMPACT_GOOGLE_LOG_INFO, LogMes...
+#include // for size_t
+#include // for uint32_t
+#include // IWYU pragma: keep
+#include // for max
+#include // for client, client::connect_state
+#include // for reply
+#include // for redis_error
+#include // for future
+#include // for operator<<, basic_ostream, size_t
+#include // for _Node_iterator, unordered_map
+#include // for move, pair
+#include // for vector
+#include "ServiceConfigLoader.h" // for ServiceConfigLoader
+#include "SessionState.h" // for SessionState
+#include "StoredState.h" // for deserialize_stored_session, ser...
+#include "magma_logging.h" // for MERROR, MLOG
+namespace magma {
+class StaticRuleStore;
+}
namespace magma {
namespace lte {
diff --git a/lte/gateway/c/session_manager/RedisStoreClient.h b/lte/gateway/c/session_manager/RedisStoreClient.h
index a60f21b2d2f3..1777098e7e87 100644
--- a/lte/gateway/c/session_manager/RedisStoreClient.h
+++ b/lte/gateway/c/session_manager/RedisStoreClient.h
@@ -14,13 +14,14 @@
#pragma once
#include
-#include
-#include
-#include
-
-#include "StoreClient.h"
-#include "StoredState.h"
-#include "ServiceConfigLoader.h"
+#include // IWYU pragma: keep
+#include // for shared_ptr
+#include // for set
+#include // for string
+#include "StoreClient.h" // for SessionMap, SessionVector, StoreClient
+namespace magma {
+class StaticRuleStore;
+}
namespace magma {
namespace lte {
diff --git a/lte/gateway/c/session_manager/SessionState.cpp b/lte/gateway/c/session_manager/SessionState.cpp
index e9bb7a76465d..f23133e045d8 100644
--- a/lte/gateway/c/session_manager/SessionState.cpp
+++ b/lte/gateway/c/session_manager/SessionState.cpp
@@ -523,11 +523,12 @@ void SessionState::apply_session_static_rule_set(
if (!is_static_rule_installed(static_rule_id)) {
MLOG(MINFO) << "Installing static rule " << static_rule_id << " for "
<< session_id_;
- activate_static_rule(static_rule_id, lifetime, uc);
- rules_to_activate.rules.push_back(rule);
+ uint32_t version = activate_static_rule(static_rule_id, lifetime, uc);
+ // Set up rules_to_activate
+ rules_to_activate.append_versioned_policy(rule, version);
}
}
- std::vector static_rules_to_deactivate;
+ std::vector static_rules_to_deactivate;
// Go through the existing rules and uninstall any rule not in the rule set
for (const auto static_rule_id : active_static_rules_) {
@@ -538,16 +539,22 @@ void SessionState::apply_session_static_rule_set(
<< " is not found. Skipping deactivation";
continue;
}
- static_rules_to_deactivate.push_back(static_rule_id);
- rules_to_deactivate.rules.push_back(rule);
+ static_rules_to_deactivate.push_back(rule);
}
}
// Do the actual removal separately so we're not modifying the vector while
// looping
- for (const auto static_rule_id : static_rules_to_deactivate) {
- MLOG(MINFO) << "Removing static rule " << static_rule_id << " for "
+ for (const PolicyRule static_rule : static_rules_to_deactivate) {
+ MLOG(MINFO) << "Removing static rule " << static_rule.id() << " for "
<< session_id_;
- deactivate_static_rule(static_rule_id, uc);
+ optional op_version =
+ deactivate_static_rule(static_rule.id(), uc);
+ if (!op_version) {
+ MLOG(MWARNING) << "Failed to deactivate static rule " << static_rule.id()
+ << " for " << session_id_;
+ } else {
+ rules_to_deactivate.append_versioned_policy(static_rule, *op_version);
+ }
}
}
@@ -561,18 +568,21 @@ void SessionState::apply_session_dynamic_rule_set(
if (!is_dynamic_rule_installed(dynamic_rule_pair.first)) {
MLOG(MINFO) << "Installing dynamic rule " << dynamic_rule_pair.first
<< " for " << session_id_;
- insert_dynamic_rule(dynamic_rule_pair.second, lifetime, uc);
- rules_to_activate.rules.push_back(dynamic_rule_pair.second);
+ uint32_t version =
+ insert_dynamic_rule(dynamic_rule_pair.second, lifetime, uc);
+ rules_to_activate.append_versioned_policy(
+ dynamic_rule_pair.second, version);
}
}
std::vector active_dynamic_rules;
dynamic_rules_.get_rules(active_dynamic_rules);
for (const auto& dynamic_rule : active_dynamic_rules) {
if (dynamic_rules.find(dynamic_rule.id()) == dynamic_rules.end()) {
+ optional op_version =
+ remove_dynamic_rule(dynamic_rule.id(), nullptr, uc);
MLOG(MINFO) << "Removing dynamic rule " << dynamic_rule.id() << " for "
<< session_id_;
- remove_dynamic_rule(dynamic_rule.id(), nullptr, uc);
- rules_to_deactivate.rules.push_back(dynamic_rule);
+ rules_to_deactivate.append_versioned_policy(dynamic_rule, *op_version);
}
}
}
@@ -835,10 +845,20 @@ void SessionState::get_session_info(SessionState::SessionInfo& info) {
dynamic_rules_.get_rules(info.gx_rules.rules);
gy_dynamic_rules_.get_rules(info.gy_dynamic_rules.rules);
+ // Set versions
+ for (const PolicyRule rule : info.gx_rules.rules) {
+ info.gx_rules.versions.push_back(get_current_rule_version(rule.id()));
+ }
+ for (const PolicyRule rule : info.gy_dynamic_rules.rules) {
+ info.gy_dynamic_rules.versions.push_back(
+ get_current_rule_version(rule.id()));
+ }
+
for (const std::string& rule_id : active_static_rules_) {
PolicyRule rule;
if (static_rules_.get_rule(rule_id, &rule)) {
- info.gx_rules.rules.push_back(rule);
+ info.gx_rules.append_versioned_policy(
+ rule, get_current_rule_version(rule_id));
}
}
}
@@ -866,7 +886,7 @@ void SessionState::remove_all_rules_for_termination(
}
gy_dynamic_rules_.get_rules(gy_dynamic_rules);
for (PolicyRule& policy : gy_dynamic_rules) {
- remove_gy_dynamic_rule(policy.id(), nullptr, session_uc);
+ remove_gy_rule(policy.id(), nullptr, session_uc);
}
for (const std::string& rule_id : active_static_rules_) {
deactivate_static_rule(rule_id, session_uc);
@@ -874,7 +894,7 @@ void SessionState::remove_all_rules_for_termination(
// remove scheduled rules
for (const std::string& rule_id : scheduled_static_rules_) {
- deactivate_scheduled_static_rule(rule_id, session_uc);
+ deactivate_scheduled_static_rule(rule_id);
}
scheduled_dynamic_rules_.get_rules(scheduled_dynamic_rules);
for (PolicyRule& policy : scheduled_dynamic_rules) {
@@ -946,49 +966,53 @@ bool SessionState::is_static_rule_installed(const std::string& rule_id) {
rule_id) != active_static_rules_.end();
}
-void SessionState::insert_dynamic_rule(
+uint32_t SessionState::insert_dynamic_rule(
const PolicyRule& rule, RuleLifetime& lifetime,
- SessionStateUpdateCriteria& update_criteria) {
- if (is_dynamic_rule_installed(rule.id())) {
- return;
- }
+ SessionStateUpdateCriteria& session_uc) {
rule_lifetimes_[rule.id()] = lifetime;
dynamic_rules_.insert_rule(rule);
- update_criteria.dynamic_rules_to_install.push_back(rule);
- update_criteria.new_rule_lifetimes[rule.id()] = lifetime;
+ session_uc.dynamic_rules_to_install.push_back(rule);
+ session_uc.new_rule_lifetimes[rule.id()] = lifetime;
+
+ increment_rule_stats(rule.id(), session_uc);
+ return get_current_rule_version(rule.id());
}
-void SessionState::insert_gy_dynamic_rule(
+uint32_t SessionState::insert_gy_rule(
const PolicyRule& rule, RuleLifetime& lifetime,
- SessionStateUpdateCriteria& update_criteria) {
- if (is_gy_dynamic_rule_installed(rule.id())) {
- MLOG(MDEBUG) << "Tried to insert " << rule.id()
- << " (gy dynamic rule), but it already existed";
- return;
- }
+ SessionStateUpdateCriteria& session_uc) {
rule_lifetimes_[rule.id()] = lifetime;
gy_dynamic_rules_.insert_rule(rule);
- update_criteria.gy_dynamic_rules_to_install.push_back(rule);
- update_criteria.new_rule_lifetimes[rule.id()] = lifetime;
+ session_uc.gy_dynamic_rules_to_install.push_back(rule);
+ session_uc.new_rule_lifetimes[rule.id()] = lifetime;
+
+ increment_rule_stats(rule.id(), session_uc);
+ return get_current_rule_version(rule.id());
}
-void SessionState::activate_static_rule(
+uint32_t SessionState::activate_static_rule(
const std::string& rule_id, RuleLifetime& lifetime,
- SessionStateUpdateCriteria& update_criteria) {
+ SessionStateUpdateCriteria& session_uc) {
rule_lifetimes_[rule_id] = lifetime;
active_static_rules_.push_back(rule_id);
- update_criteria.static_rules_to_install.insert(rule_id);
- update_criteria.new_rule_lifetimes[rule_id] = lifetime;
-}
+ session_uc.static_rules_to_install.insert(rule_id);
+ session_uc.new_rule_lifetimes[rule_id] = lifetime;
+
+ increment_rule_stats(rule_id, session_uc);
+ return get_current_rule_version(rule_id);
+};
-bool SessionState::remove_dynamic_rule(
+optional SessionState::remove_dynamic_rule(
const std::string& rule_id, PolicyRule* rule_out,
- SessionStateUpdateCriteria& update_criteria) {
+ SessionStateUpdateCriteria& session_uc) {
bool removed = dynamic_rules_.remove_rule(rule_id, rule_out);
- if (removed) {
- update_criteria.dynamic_rules_to_uninstall.insert(rule_id);
+ if (!removed) {
+ return {};
}
- return removed;
+
+ session_uc.dynamic_rules_to_uninstall.insert(rule_id);
+ increment_rule_stats(rule_id, session_uc);
+ return get_current_rule_version(rule_id);
}
bool SessionState::remove_scheduled_dynamic_rule(
@@ -1001,30 +1025,36 @@ bool SessionState::remove_scheduled_dynamic_rule(
return removed;
}
-bool SessionState::remove_gy_dynamic_rule(
+optional SessionState::remove_gy_rule(
const std::string& rule_id, PolicyRule* rule_out,
- SessionStateUpdateCriteria& update_criteria) {
+ SessionStateUpdateCriteria& session_uc) {
bool removed = gy_dynamic_rules_.remove_rule(rule_id, rule_out);
- if (removed) {
- update_criteria.gy_dynamic_rules_to_uninstall.insert(rule_id);
+ if (!removed) {
+ return {};
}
- return removed;
+ session_uc.gy_dynamic_rules_to_uninstall.insert(rule_id);
+
+ increment_rule_stats(rule_id, session_uc);
+ return get_current_rule_version(rule_id);
}
-bool SessionState::deactivate_static_rule(
- const std::string& rule_id, SessionStateUpdateCriteria& update_criteria) {
+optional SessionState::deactivate_static_rule(
+ const std::string& rule_id, SessionStateUpdateCriteria& session_uc) {
auto it = std::find(
active_static_rules_.begin(), active_static_rules_.end(), rule_id);
if (it == active_static_rules_.end()) {
- return false;
+ return {};
}
- update_criteria.static_rules_to_uninstall.insert(rule_id);
+
+ session_uc.static_rules_to_uninstall.insert(rule_id);
active_static_rules_.erase(it);
- return true;
+
+ increment_rule_stats(rule_id, session_uc);
+ return get_current_rule_version(rule_id);
}
bool SessionState::deactivate_scheduled_static_rule(
- const std::string& rule_id, SessionStateUpdateCriteria& update_criteria) {
+ const std::string& rule_id) {
if (scheduled_static_rules_.count(rule_id) == 0) {
return false;
}
@@ -1033,21 +1063,22 @@ bool SessionState::deactivate_scheduled_static_rule(
}
void SessionState::sync_rules_to_time(
- std::time_t current_time, SessionStateUpdateCriteria& update_criteria) {
+ std::time_t current_time, SessionStateUpdateCriteria& session_uc) {
// Update active static rules
for (const std::string& rule_id : active_static_rules_) {
if (should_rule_be_deactivated(rule_id, current_time)) {
- deactivate_static_rule(rule_id, update_criteria);
+ deactivate_static_rule(rule_id, session_uc);
}
}
// Update scheduled static rules
std::set scheduled_rule_ids = scheduled_static_rules_;
for (const std::string& rule_id : scheduled_rule_ids) {
if (should_rule_be_active(rule_id, current_time)) {
- install_scheduled_static_rule(rule_id, update_criteria);
+ scheduled_static_rules_.erase(rule_id);
+ activate_static_rule(rule_id, rule_lifetimes_[rule_id], session_uc);
} else if (should_rule_be_deactivated(rule_id, current_time)) {
scheduled_static_rules_.erase(rule_id);
- update_criteria.static_rules_to_uninstall.insert(rule_id);
+ deactivate_static_rule(rule_id, session_uc);
}
}
// Update active dynamic rules
@@ -1055,7 +1086,7 @@ void SessionState::sync_rules_to_time(
dynamic_rules_.get_rule_ids(dynamic_rule_ids);
for (const std::string& rule_id : dynamic_rule_ids) {
if (should_rule_be_deactivated(rule_id, current_time)) {
- remove_dynamic_rule(rule_id, NULL, update_criteria);
+ remove_dynamic_rule(rule_id, NULL, session_uc);
}
}
// Update scheduled dynamic rules
@@ -1063,9 +1094,11 @@ void SessionState::sync_rules_to_time(
scheduled_dynamic_rules_.get_rule_ids(dynamic_rule_ids);
for (const std::string& rule_id : dynamic_rule_ids) {
if (should_rule_be_active(rule_id, current_time)) {
- install_scheduled_dynamic_rule(rule_id, update_criteria);
+ PolicyRule dy_rule;
+ remove_scheduled_dynamic_rule(rule_id, &dy_rule, session_uc);
+ insert_dynamic_rule(dy_rule, rule_lifetimes_[rule_id], session_uc);
} else if (should_rule_be_deactivated(rule_id, current_time)) {
- remove_scheduled_dynamic_rule(rule_id, NULL, update_criteria);
+ remove_scheduled_dynamic_rule(rule_id, NULL, session_uc);
}
}
}
@@ -1123,32 +1156,6 @@ void SessionState::schedule_static_rule(
scheduled_static_rules_.insert(rule_id);
}
-void SessionState::install_scheduled_dynamic_rule(
- const std::string& rule_id, SessionStateUpdateCriteria& update_criteria) {
- PolicyRule dynamic_rule;
- bool removed = scheduled_dynamic_rules_.remove_rule(rule_id, &dynamic_rule);
- if (!removed) {
- MLOG(MERROR) << "Failed to mark a scheduled dynamic rule as installed "
- << "with rule_id: " << rule_id;
- return;
- }
- update_criteria.dynamic_rules_to_install.push_back(dynamic_rule);
- dynamic_rules_.insert_rule(dynamic_rule);
-}
-
-void SessionState::install_scheduled_static_rule(
- const std::string& rule_id, SessionStateUpdateCriteria& update_criteria) {
- auto it = scheduled_static_rules_.find(rule_id);
- if (it == scheduled_static_rules_.end()) {
- MLOG(MERROR) << "Failed to mark a scheduled static rule as installed "
- "with rule_id: "
- << rule_id;
- }
- update_criteria.static_rules_to_install.insert(rule_id);
- scheduled_static_rules_.erase(rule_id);
- active_static_rules_.push_back(rule_id);
-}
-
uint32_t SessionState::get_credit_key_count() {
return credit_map_.size() + monitor_map_.size();
}
@@ -1377,30 +1384,29 @@ bool SessionState::is_credit_suspended(const CreditKey& charging_key) {
return false;
}
-void SessionState::get_unsuspended_rules(RulesToProcess& rulesToProcess) {
- for (auto const& it : credit_map_) {
- CreditKey ckey = it.first;
- if (!it.second->get_suspended()) {
- get_rules_per_credit_key(ckey, rulesToProcess);
- }
- }
-}
-
void SessionState::get_rules_per_credit_key(
- CreditKey charging_key, RulesToProcess& rulesToProcess) {
- std::vector static_rules;
- static_rules_.get_rule_ids_for_charging_key(charging_key, static_rules);
- for (auto rule_id : static_rules) {
- PolicyRule rule;
- if (static_rules_.get_rule(rule_id, &rule)) {
- rulesToProcess.rules.push_back(rule);
- } else {
- MLOG(MWARNING) << "Static rule " << rule_id
- << " is not found in the system";
+ CreditKey charging_key, RulesToProcess& to_process,
+ SessionStateUpdateCriteria& session_uc) {
+ std::vector static_rules, dynamic_rules;
+ static_rules_.get_rule_definitions_for_charging_key(
+ charging_key, static_rules);
+ for (PolicyRule rule : static_rules) {
+ // Since the static rule store is shared across sessions, we should check
+ // that the rule is activated for the session
+ bool is_installed = is_static_rule_installed(rule.id());
+ if (is_installed) {
+ increment_rule_stats(rule.id(), session_uc);
+ to_process.append_versioned_policy(
+ rule, get_current_rule_version(rule.id()));
}
}
dynamic_rules_.get_rule_definitions_for_charging_key(
- charging_key, rulesToProcess.rules);
+ charging_key, dynamic_rules);
+ for (PolicyRule rule : dynamic_rules) {
+ increment_rule_stats(rule.id(), session_uc);
+ to_process.append_versioned_policy(
+ rule, get_current_rule_version(rule.id()));
+ }
}
uint64_t SessionState::get_charging_credit(
@@ -1515,8 +1521,8 @@ CreditUsageUpdate SessionState::make_credit_usage_update_req(
fill_protos_tgpp_context(req.mutable_tgpp_ctx());
req.mutable_common_context()->CopyFrom(config_.common_context);
- // TODO keep RAT specific fields separate for now as we may not always want to
- // send the entire context
+ // TODO keep RAT specific fields separate for now as we may not always want
+ // to send the entire context
if (config_.rat_specific_context.has_lte_context()) {
const auto& lte_context = config_.rat_specific_context.lte_context();
req.set_spgw_ipv4(lte_context.spgw_ipv4());
@@ -1563,10 +1569,8 @@ void SessionState::get_charging_updates(
PolicyRule redirect_rule = make_redirect_rule(grant);
if (!is_gy_dynamic_rule_installed(redirect_rule.id())) {
- RuleLifetime lifetime;
- insert_gy_dynamic_rule(redirect_rule, lifetime, uc);
- fill_service_action_with_context(action, action_type, key);
- fill_service_action_for_redirect(action, key, grant, redirect_rule);
+ fill_service_action_for_redirect(
+ action, key, grant, redirect_rule, uc);
actions_out->push_back(std::move(action));
}
@@ -1579,14 +1583,12 @@ void SessionState::get_charging_updates(
}
grant->set_service_state(SERVICE_RESTRICTED, *credit_uc);
- fill_service_action_with_context(action, action_type, key);
- fill_service_action_for_restrict(action, key, grant);
+ fill_service_action_for_restrict(action, key, grant, uc);
actions_out->push_back(std::move(action));
break;
}
case ACTIVATE_SERVICE:
- fill_service_action_with_context(action, action_type, key);
- fill_service_action_for_activate(action, key);
+ fill_service_action_for_activate(action, key, uc);
actions_out->push_back(std::move(action));
grant->set_suspended(false, credit_uc);
break;
@@ -1643,20 +1645,32 @@ optional SessionState::get_update_for_continue_service(
}
void SessionState::fill_service_action_for_activate(
- std::unique_ptr& action_p, const CreditKey& key) {
- std::vector rules;
- static_rules_.get_rules_by_ids(active_static_rules_, rules);
- dynamic_rules_.get_rule_definitions_for_charging_key(key, rules);
+ std::unique_ptr& action_p, const CreditKey& key,
+ SessionStateUpdateCriteria& session_uc) {
+ std::vector static_rules, dynamic_rules;
+ fill_service_action_with_context(action_p, ACTIVATE_SERVICE, key);
+ static_rules_.get_rules_by_ids(active_static_rules_, static_rules);
+ dynamic_rules_.get_rule_definitions_for_charging_key(key, dynamic_rules);
RulesToProcess* to_install = action_p->get_mutable_gx_rules_to_install();
- for (PolicyRule rule : rules) {
- to_install->rules.push_back(rule);
+ for (PolicyRule rule : static_rules) {
+ RuleLifetime lifetime;
+ uint32_t version = activate_static_rule(rule.id(), lifetime, session_uc);
+ to_install->append_versioned_policy(rule, version);
+ }
+ for (PolicyRule rule : dynamic_rules) {
+ RuleLifetime lifetime;
+ uint32_t version = insert_dynamic_rule(rule, lifetime, session_uc);
+ to_install->append_versioned_policy(rule, version);
}
}
void SessionState::fill_service_action_for_restrict(
std::unique_ptr& action_p, const CreditKey& key,
- std::unique_ptr& grant) {
+ std::unique_ptr& grant,
+ SessionStateUpdateCriteria& session_uc) {
+ fill_service_action_with_context(action_p, RESTRICT_ACCESS, key);
+
RulesToProcess* gy_to_install = action_p->get_mutable_gy_rules_to_install();
for (auto& rule_id : grant->final_action_info.restrict_rules) {
PolicyRule rule;
@@ -1664,9 +1678,10 @@ void SessionState::fill_service_action_for_restrict(
MLOG(MWARNING) << "Static rule " << rule_id
<< " requested as a restrict rule is not found.";
continue;
- } else {
- gy_to_install->rules.push_back(rule);
}
+ RuleLifetime lifetime;
+ uint32_t version = insert_gy_rule(rule, lifetime, session_uc);
+ gy_to_install->append_versioned_policy(rule, version);
}
}
@@ -1705,9 +1720,14 @@ PolicyRule SessionState::make_redirect_rule(
void SessionState::fill_service_action_for_redirect(
std::unique_ptr& action_p, const CreditKey& key,
- std::unique_ptr& grant, PolicyRule redirect_rule) {
+ std::unique_ptr& grant, PolicyRule redirect_rule,
+ SessionStateUpdateCriteria& session_uc) {
+ fill_service_action_with_context(action_p, REDIRECT, key);
+
RulesToProcess* gy_to_install = action_p->get_mutable_gy_rules_to_install();
- gy_to_install->rules.push_back(make_redirect_rule(grant));
+ RuleLifetime lifetime;
+ uint32_t version = insert_gy_rule(redirect_rule, lifetime, session_uc);
+ gy_to_install->append_versioned_policy(redirect_rule, version);
}
void SessionState::fill_service_action_with_context(
@@ -2004,8 +2024,8 @@ void SessionState::get_event_trigger_updates(
new_req->set_event_trigger(REVALIDATION_TIMEOUT);
request_number_++;
update_criteria.request_number_increment++;
- // todo we might want to make sure that the update went successfully before
- // clearing here
+ // todo we might want to make sure that the update went successfully
+ // before clearing here
remove_event_trigger(REVALIDATION_TIMEOUT, update_criteria);
}
}
@@ -2077,16 +2097,19 @@ RulesToProcess SessionState::remove_all_final_action_rules(
switch (final_action_info.final_action) {
case ChargingCredit_FinalAction_REDIRECT: {
PolicyRule rule;
- if (remove_gy_dynamic_rule("redirect", &rule, session_uc)) {
- to_process.rules.push_back(rule);
+ optional op_version =
+ remove_gy_rule("redirect", &rule, session_uc);
+ if (op_version) {
+ to_process.append_versioned_policy(rule, *op_version);
}
} break;
case ChargingCredit_FinalAction_RESTRICT_ACCESS:
for (std::string rule_id : final_action_info.restrict_rules) {
PolicyRule rule;
- if (static_rules_.get_rule(rule_id, &rule)) {
- to_process.rules.push_back(rule);
- deactivate_static_rule(rule_id, session_uc);
+ optional op_version =
+ remove_gy_rule(rule_id, &rule, session_uc);
+ if (op_version) {
+ to_process.append_versioned_policy(rule, *op_version);
}
}
break;
@@ -2295,4 +2318,36 @@ bool RulesToProcess::empty() const {
return rules.empty();
}
+void RulesToProcess::append_versioned_policy(
+ PolicyRule rule, uint32_t version) {
+ rules.push_back(rule);
+ versions.push_back(version);
+}
+
+uint32_t SessionState::get_current_rule_version(const std::string& rule_id) {
+ if (policy_version_and_stats_.find(rule_id) ==
+ policy_version_and_stats_.end()) {
+ MLOG(MWARNING) << "RuleID " << rule_id
+ << " doesn't have a version registered for " << session_id_
+ << ", this is unexpected";
+ return 0;
+ }
+ return policy_version_and_stats_[rule_id].current_version;
+}
+
+void SessionState::increment_rule_stats(
+ const std::string& rule_id, SessionStateUpdateCriteria& session_uc) {
+ if (policy_version_and_stats_.find(rule_id) ==
+ policy_version_and_stats_.end()) {
+ policy_version_and_stats_[rule_id] = StatsPerPolicy();
+ policy_version_and_stats_[rule_id].current_version = 0;
+ policy_version_and_stats_[rule_id].last_reported_version = 0;
+ }
+ policy_version_and_stats_[rule_id].current_version++;
+
+ if (!session_uc.policy_version_and_stats) {
+ session_uc.policy_version_and_stats = policy_version_and_stats_;
+ }
+}
+
} // namespace magma
diff --git a/lte/gateway/c/session_manager/SessionState.h b/lte/gateway/c/session_manager/SessionState.h
index db6859399e88..d0c174b23842 100644
--- a/lte/gateway/c/session_manager/SessionState.h
+++ b/lte/gateway/c/session_manager/SessionState.h
@@ -38,7 +38,6 @@ typedef std::unordered_map<
CreditKey, SessionCredit::Summary, decltype(&ccHash), decltype(&ccEqual)>
ChargingCreditSummaries;
typedef std::unordered_map> MonitorMap;
-static SessionStateUpdateCriteria UNUSED_UPDATE_CRITERIA;
// Used to transform the proto message RuleSet into a more useful structure
struct RuleSetToApply {
@@ -300,6 +299,14 @@ class SessionState {
*/
optional get_policy_type(const std::string& rule_id);
+ /**
+ * @brief Get the current rule version object
+ *
+ * @param rule_id
+ * @return uint32_t
+ */
+ uint32_t get_current_rule_version(const std::string& rule_id);
+
bool is_dynamic_rule_installed(const std::string& rule_id);
bool is_gy_dynamic_rule_installed(const std::string& rule_id);
@@ -307,22 +314,41 @@ class SessionState {
bool is_static_rule_installed(const std::string& rule_id);
/**
- * Add a dynamic rule to the session which is currently active.
+ * @brief Add a dynamic rule into dynamic rule store. Increment the associated
+ * version and return the new version.
+ *
+ * @param rule
+ * @param lifetime
+ * @param session_uc
+ * @return uint32_t updated version
*/
- void insert_dynamic_rule(
+ uint32_t insert_dynamic_rule(
const PolicyRule& rule, RuleLifetime& lifetime,
- SessionStateUpdateCriteria& update_criteria);
+ SessionStateUpdateCriteria& session_uc);
/**
- * Add a static rule to the session which is currently active.
+ * @brief Insert a static rule into active_static_rules_. Increment the
+ * associated version and return the new version.
+ *
+ * @param rule_id
+ * @param lifetime
+ * @param session_uc
+ * @return uint32_t updated version
*/
- void activate_static_rule(
+ uint32_t activate_static_rule(
const std::string& rule_id, RuleLifetime& lifetime,
- SessionStateUpdateCriteria& update_criteria);
-
- void insert_gy_dynamic_rule(
+ SessionStateUpdateCriteria& session_uc);
+ /**
+ * @brief Insert a PolicyRule into gy_dynamic_rules_
+ *
+ * @param rule
+ * @param lifetime
+ * @param update_criteria
+ * @return uint32_t updated version
+ */
+ uint32_t insert_gy_rule(
const PolicyRule& rule, RuleLifetime& lifetime,
- SessionStateUpdateCriteria& update_criteria);
+ SessionStateUpdateCriteria& session_uc);
/**
* Remove a currently active dynamic rule to mark it as deactivated.
@@ -332,9 +358,9 @@ class SessionState {
* @param update_criteria Tracks updates to the session. To be passed back to
* the SessionStore to resolve issues of concurrent
* updates to a session.
- * @return True if successfully removed.
+ * @return optional updated version if success, {} if failure
*/
- bool remove_dynamic_rule(
+ optional remove_dynamic_rule(
const std::string& rule_id, PolicyRule* rule_out,
SessionStateUpdateCriteria& update_criteria);
@@ -342,24 +368,32 @@ class SessionState {
const std::string& rule_id, PolicyRule* rule_out,
SessionStateUpdateCriteria& update_criteria);
- bool remove_gy_dynamic_rule(
+ /**
+ * @brief Remove a Gy rule from SessionState and increment the corresponding
+ * version
+ *
+ * @param rule_id
+ * @param rule_out
+ * @param session_uc
+ * @return optional updated version if success, {} if failure
+ */
+ optional remove_gy_rule(
const std::string& rule_id, PolicyRule* rule_out,
- SessionStateUpdateCriteria& update_criteria);
+ SessionStateUpdateCriteria& session_uc);
/**
* Remove a currently active static rule to mark it as deactivated.
*
* @param rule_id ID of the rule to be removed.
- * @param update_criteria Tracks updates to the session. To be passed back to
+ * @param session_uc Tracks updates to the session. To be passed back to
* the SessionStore to resolve issues of concurrent
* updates to a session.
- * @return True if successfully removed.
+ * @return new version if successfully removed. otherwise returns {}
*/
- bool deactivate_static_rule(
- const std::string& rule_id, SessionStateUpdateCriteria& update_criteria);
+ optional deactivate_static_rule(
+ const std::string& rule_id, SessionStateUpdateCriteria& session_uc);
- bool deactivate_scheduled_static_rule(
- const std::string& rule_id, SessionStateUpdateCriteria& update_criteria);
+ bool deactivate_scheduled_static_rule(const std::string& rule_id);
std::vector& get_static_rules();
@@ -378,6 +412,8 @@ class SessionState {
const PolicyRule& rule, RuleLifetime& lifetime,
SessionStateUpdateCriteria& update_criteria);
+ bool is_static_rule_scheduled(const std::string& rule_id);
+
/**
* Schedule a static rule for activation in the future.
*/
@@ -385,18 +421,6 @@ class SessionState {
const std::string& rule_id, RuleLifetime& lifetime,
SessionStateUpdateCriteria& update_criteria);
- /**
- * Mark a scheduled dynamic rule as activated.
- */
- void install_scheduled_dynamic_rule(
- const std::string& rule_id, SessionStateUpdateCriteria& update_criteria);
-
- /**
- * Mark a scheduled static rule as activated.
- */
- void install_scheduled_static_rule(
- const std::string& rule_id, SessionStateUpdateCriteria& update_criteria);
-
void set_suspend_credit(
const CreditKey& charging_key, bool new_suspended,
SessionStateUpdateCriteria& update_criteria);
@@ -423,10 +447,9 @@ class SessionState {
SessionFsmState get_state();
- void get_unsuspended_rules(RulesToProcess& rulesToProcess);
-
void get_rules_per_credit_key(
- CreditKey charging_key, RulesToProcess& rulesToProcess);
+ CreditKey charging_key, RulesToProcess& rulesToProcess,
+ SessionStateUpdateCriteria& session_uc);
/**
* Remove all active/scheduled static/dynamic rules and reflect the change in
@@ -576,7 +599,7 @@ class SessionState {
// Used between create session and activate session. Empty afterwards
CreateSessionResponse create_session_response_;
- // Track version tracking information
+ // Track version tracking information used for LTE/WLAN
PolicyStatsMap policy_version_and_stats_;
// All static rules synced from policy DB
@@ -643,17 +666,20 @@ class SessionState {
SessionStateUpdateCriteria& session_uc);
void fill_service_action_for_activate(
- std::unique_ptr& action, const CreditKey& key);
+ std::unique_ptr& action, const CreditKey& key,
+ SessionStateUpdateCriteria& session_uc);
void fill_service_action_for_restrict(
std::unique_ptr& action_p, const CreditKey& key,
- std::unique_ptr& grant);
+ std::unique_ptr& grant,
+ SessionStateUpdateCriteria& session_uc);
PolicyRule make_redirect_rule(std::unique_ptr& grant);
void fill_service_action_for_redirect(
std::unique_ptr& action_p, const CreditKey& key,
- std::unique_ptr& grant, PolicyRule redirect_rule);
+ std::unique_ptr& grant, PolicyRule redirect_rule,
+ SessionStateUpdateCriteria& session_uc);
void fill_service_action_with_context(
std::unique_ptr& action, ServiceActionType action_type,
@@ -732,8 +758,6 @@ class SessionState {
UpdateSessionRequest& update_request_out,
SessionStateUpdateCriteria& update_criteria);
- bool is_static_rule_scheduled(const std::string& rule_id);
-
/** apply static_rules which is the desired state for the session's rules **/
void apply_session_static_rule_set(
std::unordered_set static_rules,
@@ -793,6 +817,15 @@ class SessionState {
*/
void update_data_metrics(
const char* counter_name, uint64_t bytes_tx, uint64_t bytes_rx);
+
+ // PolicyStatsMap functions
+ /**
+ *
+ * @param rule_id
+ * @param session_uc
+ */
+ void increment_rule_stats(
+ const std::string& rule_id, SessionStateUpdateCriteria& session_uc);
};
} // namespace magma
diff --git a/lte/gateway/c/session_manager/SpgwServiceClient.cpp b/lte/gateway/c/session_manager/SpgwServiceClient.cpp
index 7dcfea792475..1f488f249b82 100644
--- a/lte/gateway/c/session_manager/SpgwServiceClient.cpp
+++ b/lte/gateway/c/session_manager/SpgwServiceClient.cpp
@@ -12,8 +12,22 @@
*/
#include "SpgwServiceClient.h"
-#include "ServiceRegistrySingleton.h"
-#include "magma_logging.h"
+#include // for COMPACT_GOOGLE_LOG...
+#include // for Channel
+#include // for default_delete
+#include // for Status
+#include // for copy
+#include // for uint32_t
+#include // for operator<<, basic_...
+#include // for move
+#include "ServiceRegistrySingleton.h" // for ServiceRegistrySin...
+#include "lte/protos/policydb.pb.h" // for RepeatedField, Rep...
+#include "lte/protos/spgw_service.grpc.pb.h" // for SpgwService::Stub
+#include "lte/protos/spgw_service.pb.h" // for DeleteBearerRequest
+#include "magma_logging.h" // for MLOG, MERROR, MINFO
+namespace grpc {
+class Channel;
+}
using grpc::Status;
diff --git a/lte/gateway/c/session_manager/SpgwServiceClient.h b/lte/gateway/c/session_manager/SpgwServiceClient.h
index 4ccd6336ff25..f5158ffa2f25 100644
--- a/lte/gateway/c/session_manager/SpgwServiceClient.h
+++ b/lte/gateway/c/session_manager/SpgwServiceClient.h
@@ -12,12 +12,43 @@
*/
#pragma once
-#include
-
-#include
-#include
-
-#include "GRPCReceiver.h"
+#include // for SpgwService::Stub, Spgw...
+#include // for uint32_t
+#include // for function
+#include // for shared_ptr, unique_ptr
+#include // for string
+#include // for vector
+#include "GRPCReceiver.h" // for GRPCReceiver
+#include "lte/protos/subscriberdb.pb.h" // for lte
+namespace grpc {
+class Channel;
+}
+namespace grpc {
+class Status;
+}
+namespace grpc {
+class Status;
+}
+namespace magma {
+namespace lte {
+class CreateBearerRequest;
+}
+} // namespace magma
+namespace magma {
+namespace lte {
+class CreateBearerResult;
+}
+} // namespace magma
+namespace magma {
+namespace lte {
+class DeleteBearerRequest;
+}
+} // namespace magma
+namespace magma {
+namespace lte {
+class DeleteBearerResult;
+}
+} // namespace magma
using grpc::Status;
diff --git a/lte/gateway/c/session_manager/Types.h b/lte/gateway/c/session_manager/Types.h
index 6f0e940a1005..8cba4d0decd8 100644
--- a/lte/gateway/c/session_manager/Types.h
+++ b/lte/gateway/c/session_manager/Types.h
@@ -185,7 +185,9 @@ struct RulesToProcess {
// If this vector is set, then it has PolicyRule definitions for both static
// and dynamic rules
std::vector rules;
+ std::vector versions;
bool empty() const;
+ void append_versioned_policy(PolicyRule rule, uint32_t version);
};
struct StatsPerPolicy {
diff --git a/lte/gateway/c/session_manager/sessiond_main.cpp b/lte/gateway/c/session_manager/sessiond_main.cpp
index fa8281dbda0e..1c368a33bb18 100644
--- a/lte/gateway/c/session_manager/sessiond_main.cpp
+++ b/lte/gateway/c/session_manager/sessiond_main.cpp
@@ -11,6 +11,7 @@
* limitations under the License.
*/
+#include
#include
#include
@@ -43,6 +44,38 @@
extern "C" void __gcov_flush(void);
#endif
+// TODO remove this flag once we are on Ubuntu 20.04 by default in 1.6
+#if SENTRY_ENABLED
+#include "sentry.h"
+
+#define COMMIT_HASH_ENV "COMMIT_HASH"
+#define CONTROL_PROXY_SERVICE_NAME "control_proxy"
+#define SENTRY_URL "sentry_url"
+
+void initialize_sentry() {
+ auto control_proxy_config =
+ magma::ServiceConfigLoader{}.load_service_config(CONTROL_PROXY_SERVICE_NAME);
+ if (control_proxy_config[SENTRY_URL].IsDefined()) {
+ const std::string sentry_dns =
+ control_proxy_config[SENTRY_URL].as();
+ sentry_options_t* options = sentry_options_new();
+ sentry_options_set_dsn(options, sentry_dns.c_str());
+
+ if (const char* commit_hash_p = std::getenv(COMMIT_HASH_ENV)) {
+ sentry_options_set_release(options, commit_hash_p);
+ }
+
+ sentry_init(options);
+ sentry_capture_event(sentry_value_new_message_event(
+ SENTRY_LEVEL_INFO, "", "Starting SessionD with Sentry!"));
+ }
+}
+
+void shutdown_sentry() {
+ sentry_shutdown();
+}
+#endif
+
static magma::mconfig::SessionD get_default_mconfig() {
magma::mconfig::SessionD mconfig;
mconfig.set_log_level(magma::orc8r::LogLevel::INFO);
@@ -172,6 +205,10 @@ int main(int argc, char* argv[]) {
__gcov_flush();
#endif
+#ifdef SENTRY_ENABLED
+ initialize_sentry();
+#endif
+
magma::init_logging(argv[0]);
auto mconfig = load_mconfig();
@@ -423,5 +460,8 @@ int main(int argc, char* argv[]) {
}
delete session_store;
+#ifdef SENTRY_ENABLED
+ shutdown_sentry();
+#endif
return 0;
}
diff --git a/lte/gateway/c/session_manager/test/Matchers.h b/lte/gateway/c/session_manager/test/Matchers.h
index 4d52353347b8..1134cf09f3e9 100644
--- a/lte/gateway/c/session_manager/test/Matchers.h
+++ b/lte/gateway/c/session_manager/test/Matchers.h
@@ -102,9 +102,9 @@ MATCHER_P3(CheckTerminateRequestCount, imsi, monitorCount, chargingCount, "") {
req.monitor_usages().size() == monitorCount;
}
-MATCHER_P5(
+MATCHER_P6(
CheckSessionInfos, imsi_list, ip_address_list, ipv6_address_list, cfg,
- rule_ids_lists, "") {
+ rule_ids_lists, versions_lists, "") {
auto infos = static_cast>(arg);
if (infos.size() != imsi_list.size()) {
@@ -131,6 +131,13 @@ MATCHER_P5(
if (info.gx_rules.rules[r_index].id() != expected_gx_rules[r_index])
return false;
}
+
+ std::vector expected_versions = versions_lists[i];
+ for (size_t r_index = 0; i < info.gx_rules.versions.size(); i++) {
+ if (info.gx_rules.versions[r_index] != expected_versions[r_index])
+ return false;
+ }
+
// check ambr field if config has qos_info
if (cfg.rat_specific_context.has_lte_context() &&
cfg.rat_specific_context.lte_context().has_qos_info()) {
@@ -241,13 +248,12 @@ MATCHER_P6(
CheckActivateFlowsForTunnIds, imsi, ipv4, ipv6, enb_teid, agw_teid,
rule_count, "") {
auto request = static_cast(arg);
- std::cerr << "Got dynamic size : " << request->dynamic_rules_size()
- << std::endl;
+ std::cerr << "Got " << request->policies_size() << " rules" << std::endl;
auto res = request->sid().id() == imsi && request->ip_addr() == ipv4 &&
request->ipv6_addr() == ipv6 &&
request->uplink_tunnel() == agw_teid &&
request->downlink_tunnel() == enb_teid &&
- request->dynamic_rules_size() == rule_count;
+ request->policies_size() == rule_count;
return res;
}
diff --git a/lte/gateway/c/session_manager/test/SessionStateTester.h b/lte/gateway/c/session_manager/test/SessionStateTester.h
index dae0b25304ad..8565ff24213c 100644
--- a/lte/gateway/c/session_manager/test/SessionStateTester.h
+++ b/lte/gateway/c/session_manager/test/SessionStateTester.h
@@ -38,10 +38,6 @@ class SessionStateTest : public ::testing::Test {
pdp_start_time, CreateSessionResponse{});
update_criteria = get_default_update_criteria();
}
- enum RuleType {
- STATIC = 0,
- DYNAMIC = 1,
- };
void insert_static_rule_into_store(
uint32_t rating_group, const std::string& m_key,
@@ -51,9 +47,9 @@ class SessionStateTest : public ::testing::Test {
rule_store->insert_rule(rule);
}
- void insert_rule(
+ uint32_t insert_rule(
uint32_t rating_group, const std::string& m_key,
- const std::string& rule_id, RuleType rule_type,
+ const std::string& rule_id, PolicyType rule_type,
std::time_t activation_time, std::time_t deactivation_time) {
PolicyRule rule;
create_policy_rule(rule_id, m_key, rating_group, &rule);
@@ -63,17 +59,19 @@ class SessionStateTest : public ::testing::Test {
// insert into list of existing rules
rule_store->insert_rule(rule);
// mark the rule as active in session
- session_state->activate_static_rule(rule_id, lifetime, update_criteria);
- break;
+ return session_state->activate_static_rule(
+ rule_id, lifetime, update_criteria);
case DYNAMIC:
- session_state->insert_dynamic_rule(rule, lifetime, update_criteria);
+ return session_state->insert_dynamic_rule(
+ rule, lifetime, update_criteria);
break;
}
+ return 0;
}
void schedule_rule(
uint32_t rating_group, const std::string& m_key,
- const std::string& rule_id, RuleType rule_type,
+ const std::string& rule_id, PolicyType rule_type,
std::time_t activation_time, std::time_t deactivation_time) {
PolicyRule rule;
create_policy_rule(rule_id, m_key, rating_group, &rule);
@@ -108,7 +106,7 @@ class SessionStateTest : public ::testing::Test {
}
}
- void insert_gy_redirection_rule(const std::string& rule_id) {
+ uint32_t insert_gy_redirection_rule(const std::string& rule_id) {
PolicyRule redirect_rule;
redirect_rule.set_id(rule_id);
redirect_rule.set_priority(999);
@@ -126,7 +124,7 @@ class SessionStateTest : public ::testing::Test {
redirect_server.redirect_server_address());
RuleLifetime lifetime{};
- session_state->insert_gy_dynamic_rule(
+ return session_state->insert_gy_rule(
redirect_rule, lifetime, update_criteria);
}
@@ -163,9 +161,9 @@ class SessionStateTest : public ::testing::Test {
session_state->receive_monitor(monitor_resp, update_criteria);
}
- void activate_rule(
+ uint32_t activate_rule(
uint32_t rating_group, const std::string& m_key,
- const std::string& rule_id, RuleType rule_type,
+ const std::string& rule_id, PolicyType rule_type,
std::time_t activation_time, std::time_t deactivation_time) {
PolicyRule rule;
create_policy_rule(rule_id, m_key, rating_group, &rule);
@@ -173,12 +171,17 @@ class SessionStateTest : public ::testing::Test {
switch (rule_type) {
case STATIC:
rule_store->insert_rule(rule);
- session_state->activate_static_rule(rule_id, lifetime, update_criteria);
+ return session_state->activate_static_rule(
+ rule_id, lifetime, update_criteria);
break;
case DYNAMIC:
- session_state->insert_dynamic_rule(rule, lifetime, update_criteria);
+ return session_state->insert_dynamic_rule(
+ rule, lifetime, update_criteria);
+ break;
+ default:
break;
}
+ return 0;
}
protected:
diff --git a/lte/gateway/c/session_manager/test/test_local_enforcer.cpp b/lte/gateway/c/session_manager/test/test_local_enforcer.cpp
index 037efdfa9380..0111ce191dc5 100644
--- a/lte/gateway/c/session_manager/test/test_local_enforcer.cpp
+++ b/lte/gateway/c/session_manager/test/test_local_enforcer.cpp
@@ -762,12 +762,18 @@ TEST_F(LocalEnforcerTest, test_sync_sessions_on_restart) {
.activation_time = std::time_t(15),
.deactivation_time = std::time_t(20),
};
- auto& uc = session_update[IMSI1][SESSION_ID_1];
- session_map_2[IMSI1].front()->activate_static_rule("rule1", lifetime1, uc);
+ auto& uc = session_update[IMSI1][SESSION_ID_1];
+ uint32_t v1 = session_map_2[IMSI1].front()->activate_static_rule(
+ "rule1", lifetime1, uc);
session_map_2[IMSI1].front()->schedule_static_rule("rule2", lifetime2, uc);
session_map_2[IMSI1].front()->schedule_static_rule("rule3", lifetime3, uc);
session_map_2[IMSI1].front()->schedule_static_rule("rule4", lifetime4, uc);
+ EXPECT_EQ(v1, 1);
+
+ EXPECT_TRUE(uc.policy_version_and_stats);
+ EXPECT_EQ((*uc.policy_version_and_stats)["rule1"].current_version, 1);
+
EXPECT_EQ(uc.static_rules_to_install.count("rule1"), 1);
EXPECT_EQ(uc.new_scheduled_static_rules.count("rule2"), 1);
EXPECT_EQ(uc.new_scheduled_static_rules.count("rule3"), 1);
@@ -1088,6 +1094,7 @@ TEST_F(LocalEnforcerTest, test_credit_init_with_transient_error_redirect) {
// insert initial session credit
CreateSessionResponse response;
auto credits = response.mutable_credits();
+ response.mutable_static_rules()->Add()->set_rule_id("rule1");
create_credit_update_response_with_error(
IMSI1, SESSION_ID_1, 1, false, DIAMETER_CREDIT_LIMIT_REACHED,
ChargingCredit_FinalAction_REDIRECT, "12.7.7.4", "", credits->Add());
@@ -1169,12 +1176,16 @@ TEST_F(LocalEnforcerTest, test_update_with_transient_error) {
insert_static_rule(1, "", "rule2");
insert_static_rule(2, "", "rule3");
- // insert initial session credit
+ // insert initial session credit + rules
CreateSessionResponse response;
create_credit_update_response(
IMSI1, SESSION_ID_1, 1, 1024, response.mutable_credits()->Add());
create_credit_update_response(
IMSI1, SESSION_ID_1, 2, 1024, response.mutable_credits()->Add());
+ response.mutable_static_rules()->Add()->set_rule_id("rule1");
+ response.mutable_static_rules()->Add()->set_rule_id("rule2");
+ response.mutable_static_rules()->Add()->set_rule_id("rule3");
+
local_enforcer->init_session(
session_map, IMSI1, SESSION_ID_1, test_cfg_, response);
local_enforcer->update_tunnel_ids(
@@ -1218,6 +1229,7 @@ TEST_F(LocalEnforcerTest, test_reauth_with_redirected_suspended_credit) {
// 1- INITIAL SET UP TO CREATE A REDIRECTED due to SUSPENDED CREDIT
// insert initial suspended and redirected credit
CreateSessionResponse response;
+ response.mutable_static_rules()->Add()->set_rule_id("rule1");
auto credits = response.mutable_credits();
test_cfg_.common_context.mutable_sid()->set_id(IMSI1);
create_credit_update_response_with_error(
@@ -1427,7 +1439,7 @@ TEST_F(LocalEnforcerTest, test_installing_rules_with_activation_time) {
CreateSessionResponse response;
create_credit_update_response(
IMSI1, SESSION_ID_1, 1, 1024, true, response.mutable_credits()->Add());
- auto now = time(NULL);
+ auto now = time(nullptr);
// add a dynamic rule without activation time
auto dynamic_rule = response.mutable_dynamic_rules()->Add();
@@ -1826,7 +1838,7 @@ TEST_F(LocalEnforcerTest, test_rar_create_dedicated_bearer) {
std::vector usage_monitoring_credits;
create_policy_reauth_request(
SESSION_ID_1, IMSI1, rules_to_remove, rules_to_install,
- dynamic_rules_to_install, event_triggers, time(NULL),
+ dynamic_rules_to_install, event_triggers, time(nullptr),
usage_monitoring_credits, &rar);
auto rar_qos_info = rar.mutable_qos_info();
rar_qos_info->set_qci(QCI_1);
@@ -2180,7 +2192,7 @@ TEST_F(LocalEnforcerTest, test_rar_session_not_found) {
// verify session validity by passing in an invalid IMSI
PolicyReAuthRequest rar;
create_policy_reauth_request(
- "session1", IMSI1, {}, {}, {}, {}, time(NULL), {}, &rar);
+ "session1", IMSI1, {}, {}, {}, {}, time(nullptr), {}, &rar);
PolicyReAuthAnswer raa;
auto update = SessionStore::get_default_session_update(session_map);
local_enforcer->init_policy_reauth(session_map, rar, raa, update);
@@ -2212,7 +2224,7 @@ TEST_F(LocalEnforcerTest, test_revalidation_timer_on_init) {
monitor);
response.add_event_triggers(EventTrigger::REVALIDATION_TIMEOUT);
- response.mutable_revalidation_time()->set_seconds(time(NULL));
+ response.mutable_revalidation_time()->set_seconds(time(nullptr));
StaticRuleInstall static_rule_install;
static_rule_install.set_rule_id("rule1");
@@ -2267,7 +2279,7 @@ TEST_F(LocalEnforcerTest, test_revalidation_timer_on_rar) {
// Create a RaR with a REVALIDATION event trigger
create_policy_reauth_request(
- SESSION_ID_1, IMSI1, {}, {}, {}, event_triggers, time(NULL), {}, &rar);
+ SESSION_ID_1, IMSI1, {}, {}, {}, event_triggers, time(nullptr), {}, &rar);
auto update = SessionStore::get_default_session_update(session_map);
// This should trigger a revalidation to be scheduled
@@ -2330,7 +2342,7 @@ TEST_F(LocalEnforcerTest, test_revalidation_timer_on_update) {
EXPECT_EQ(session_map[IMSI1].size(), 1);
EXPECT_EQ(session_map[IMSI2].size(), 1);
- auto revalidation_timer = time(NULL);
+ auto revalidation_timer = time(nullptr);
// IMSI1 has two separate monitors with the same revalidation timer
// IMSI2 does not have a revalidation timer
auto monitor = update_response.mutable_usage_monitor_responses()->Add();
@@ -2398,7 +2410,7 @@ TEST_F(LocalEnforcerTest, test_revalidation_timer_on_update_no_monitor) {
monitor->set_sid(IMSI1);
monitor->set_session_id(SESSION_ID_1);
monitor->add_event_triggers(EventTrigger::REVALIDATION_TIMEOUT);
- monitor->mutable_revalidation_time()->set_seconds(time(NULL));
+ monitor->mutable_revalidation_time()->set_seconds(time(nullptr));
auto update = SessionStore::get_default_session_update(session_map);
// This should trigger a revalidation to be scheduled
local_enforcer->update_session_credits_and_rules(
@@ -2467,6 +2479,7 @@ TEST_F(LocalEnforcerTest, test_pipelined_cwf_setup) {
std::vector ipv6_address_list = {"", ""};
std::vector> rule_list = {{"rule22"},
{"rule1", "rule2"}};
+ std::vector> version_list = {{1}, {1, 1}};
std::vector ue_mac_addrs = {"00:00:00:00:00:02",
"11:22:00:00:22:11"};
@@ -2478,7 +2491,7 @@ TEST_F(LocalEnforcerTest, test_pipelined_cwf_setup) {
*pipelined_client, setup_cwf(
CheckSessionInfos(
imsi_list, ip_address_list, ipv6_address_list,
- test_cwf_cfg2, rule_list),
+ test_cwf_cfg2, rule_list, version_list),
testing::_, ue_mac_addrs, msisdns, apn_mac_addrs,
apn_names, testing::_, testing::_, testing::_))
.Times(1);
@@ -2534,6 +2547,7 @@ TEST_F(LocalEnforcerTest, test_pipelined_lte_setup) {
std::vector ipv6_address_list = {IPv6_1, ""};
std::vector> rule_list = {{"rule22"},
{"rule1", "rule2"}};
+ std::vector> version_list = {{1}, {1, 1}};
std::vector ue_mac_addrs = {"00:00:00:00:00:02",
"11:22:00:00:22:11"};
@@ -2545,7 +2559,7 @@ TEST_F(LocalEnforcerTest, test_pipelined_lte_setup) {
*pipelined_client, setup_lte(
CheckSessionInfos(
imsi_list, ip_address_list, ipv6_address_list,
- test_cfg_, rule_list),
+ test_cfg_, rule_list, version_list),
testing::_, testing::_))
.Times(1);
diff --git a/lte/gateway/c/session_manager/test/test_session_state.cpp b/lte/gateway/c/session_manager/test/test_session_state.cpp
index 724c85ce9e07..ef739b4ca6e2 100644
--- a/lte/gateway/c/session_manager/test/test_session_state.cpp
+++ b/lte/gateway/c/session_manager/test/test_session_state.cpp
@@ -48,12 +48,14 @@ TEST_F(SessionStateTest, test_session_rules) {
EXPECT_EQ(session_state->is_static_rule_installed("rule3"), true);
EXPECT_EQ(session_state->is_static_rule_installed("rule_DNE"), false);
+ EXPECT_EQ(session_state->get_current_rule_version("rule2"), 1);
+ EXPECT_EQ(session_state->get_current_rule_version("rule3"), 1);
+
// Test rule removals
PolicyRule rule_out;
session_state->deactivate_static_rule("rule2", update_criteria);
EXPECT_EQ(1, session_state->total_monitored_rules_count());
- EXPECT_EQ(
- true,
+ EXPECT_TRUE(
session_state->remove_dynamic_rule("rule1", &rule_out, update_criteria));
EXPECT_EQ("m1", rule_out.monitoring_key());
EXPECT_EQ(0, session_state->total_monitored_rules_count());
@@ -98,13 +100,20 @@ TEST_F(SessionStateTest, test_rule_scheduling) {
// Now suppose some time has passed, and it's time to mark scheduled rules
// as active. The responsibility is given to the session owner to make
// these calls
- session_state->install_scheduled_dynamic_rule("rule1", _uc);
+ PolicyRule rule;
+ session_state->remove_scheduled_dynamic_rule("rule1", &rule, _uc);
+ session_state->insert_dynamic_rule(
+ rule, session_state->get_rule_lifetime("rule1"), _uc);
EXPECT_EQ(1, session_state->total_monitored_rules_count());
EXPECT_TRUE(session_state->is_dynamic_rule_installed("rule1"));
- session_state->install_scheduled_static_rule("rule2", _uc);
+ session_state->activate_static_rule(
+ "rule2", session_state->get_rule_lifetime("rule2"), _uc);
EXPECT_EQ(2, session_state->total_monitored_rules_count());
EXPECT_TRUE(session_state->is_static_rule_installed("rule2"));
+
+ EXPECT_EQ(session_state->get_current_rule_version("rule1"), 1);
+ EXPECT_EQ(session_state->get_current_rule_version("rule2"), 1);
}
/**
@@ -150,7 +159,6 @@ TEST_F(SessionStateTest, test_rule_time_sync) {
EXPECT_TRUE(uc.dynamic_rules_to_uninstall.count("d3"));
EXPECT_TRUE(uc.static_rules_to_install.count("s1"));
- EXPECT_TRUE(uc.static_rules_to_uninstall.count("s3"));
// Update the time once more, sync again, and check expectations
test_time = std::time_t(16);
@@ -290,12 +298,10 @@ TEST_F(SessionStateTest, test_add_rule_usage) {
EXPECT_EQ(update.usage_monitors_size(), 2);
PolicyRule policy_out;
- EXPECT_EQ(
- true, session_state->remove_dynamic_rule(
- "dyn_rule1", &policy_out, update_criteria));
- EXPECT_EQ(
- true, session_state->deactivate_static_rule("rule1", update_criteria));
- EXPECT_EQ(false, session_state->active_monitored_rules_exist());
+ EXPECT_TRUE(session_state->remove_dynamic_rule(
+ "dyn_rule1", &policy_out, update_criteria));
+ EXPECT_TRUE(session_state->deactivate_static_rule("rule1", update_criteria));
+ EXPECT_FALSE(session_state->active_monitored_rules_exist());
EXPECT_TRUE(
std::find(
update_criteria.dynamic_rules_to_uninstall.begin(),
@@ -642,7 +648,8 @@ TEST_F(SessionStateTest, test_get_total_credit_usage_multiple_rule_shared_key) {
}
TEST_F(SessionStateTest, test_install_gy_rules) {
- insert_gy_redirection_rule("redirect");
+ uint32_t version = insert_gy_redirection_rule("redirect");
+ EXPECT_EQ(1, version);
std::vector rules_out{};
std::vector& rules_out_ptr = rules_out;
@@ -655,9 +662,11 @@ TEST_F(SessionStateTest, test_install_gy_rules) {
EXPECT_EQ(update_criteria.gy_dynamic_rules_to_install.size(), 1);
PolicyRule rule_out;
- EXPECT_EQ(
- true, session_state->remove_gy_dynamic_rule(
- "redirect", &rule_out, update_criteria));
+ optional op_version =
+ session_state->remove_gy_rule("redirect", &rule_out, update_criteria);
+ EXPECT_TRUE(op_version);
+ EXPECT_EQ(*op_version, 2);
+
// basic sanity checks to see it's properly deleted
rules_out = {};
session_state->get_gy_dynamic_rules().get_rule_ids(rules_out_ptr);
diff --git a/lte/gateway/configs/templates/mme.conf.template b/lte/gateway/configs/templates/mme.conf.template
index 503236cf8c20..e15a030a4e06 100644
--- a/lte/gateway/configs/templates/mme.conf.template
+++ b/lte/gateway/configs/templates/mme.conf.template
@@ -106,6 +106,24 @@ MME :
{% endfor %}
);
+ # List of blocked IMEIs
+ # By default this list is empty
+ # Stored in a hash table on mme side
+ # Length of IMEI=15 digits, length of IMEISV=16 digits
+ BLOCKED_IMEI_LIST = (
+ # Sample IMEI: TAC(8 digits) + SNR (6 digits)
+ #{ IMEI_TAC="99000482"; SNR="351037"}
+ # Sample IMEI without SNR: TAC(8 digits)
+ #{ IMEI_TAC="99000482";}
+ # ImeiConfig values can be found at magma/lte/protos/mconfig/mconfigs.proto
+ {% for imei_config in restrictedImeis -%}
+ {
+ IMEI_TAC = "{{ imei_config.tac }}"
+ SNR = "{{ imei_config.snr }}"
+ }{% if not loop.last %},{% endif %}
+ {% endfor %}
+ );
+
CSFB :
{
NON_EPS_SERVICE_CONTROL = "{{ non_eps_service_control }}";
diff --git a/lte/gateway/deploy/roles/dev_common/defaults/main.yml b/lte/gateway/deploy/roles/dev_common/defaults/main.yml
index 303f97b8bc8e..e7aa3b2f0a21 100644
--- a/lte/gateway/deploy/roles/dev_common/defaults/main.yml
+++ b/lte/gateway/deploy/roles/dev_common/defaults/main.yml
@@ -1,3 +1,4 @@
+tmp_directory: /var/tmp
codegen_root: /var/tmp/codegen
mvn_version: 3.5.4
mvn_sha1: 22cac91b3557586bb1eba326f2f7727543ff15e3
diff --git a/lte/gateway/deploy/roles/dev_common/tasks/main.yml b/lte/gateway/deploy/roles/dev_common/tasks/main.yml
index d1423f84e8c7..3cfbbed8d1a6 100644
--- a/lte/gateway/deploy/roles/dev_common/tasks/main.yml
+++ b/lte/gateway/deploy/roles/dev_common/tasks/main.yml
@@ -238,6 +238,7 @@
- libpcap-dev
- libtins-dev
- libmnl-dev
+ - libcurl4-openssl-dev
retries: 5
when: preburn
@@ -265,6 +266,40 @@
- libprotoc17
- libssl-dev
+###############################################
+# Download and build sentry-native
+###############################################
+
+- name: Install Sentry Native SDK
+ vars:
+ sentry_native_version: "0.4.8"
+ get_url:
+ url: "https://github.com/getsentry/sentry-native/releases/download/{{ sentry_native_version }}/sentry-native.zip"
+ dest: "{{ tmp_directory }}/sentry-native.zip"
+ when: preburn and ansible_distribution == "Ubuntu"
+
+- name: Create a directory for Sentry Native
+ file:
+ path: "{{ tmp_directory }}/sentry-native"
+ state: directory
+ when: preburn and ansible_distribution == "Ubuntu"
+
+- name: Unpack Sentry Native SDK
+ unarchive:
+ src: "{{ tmp_directory }}/sentry-native.zip"
+ dest: "{{ tmp_directory }}/sentry-native"
+ remote_src: yes
+ when: preburn and ansible_distribution == "Ubuntu"
+
+- name: Build and Install Sentry Native SDK
+ shell: |
+ cd {{ tmp_directory }}/sentry-native && \
+ cmake -B build -DCMAKE_BUILD_TYPE=RelWithDebInfo && \
+ cmake --build build --parallel && \
+ cmake --install build --prefix install --config RelWithDebInfo && \
+ cd build && make install
+ when: preburn and ansible_distribution == "Ubuntu"
+
###############################################
# Download and build swagger-codegen
###############################################
@@ -319,6 +354,13 @@
CODEGEN_ROOT: "{{ codegen_root }}"
when: preburn
+- name: Download gHZ binary from artifactory
+ get_url:
+ url: https://artifactory.magmacore.org:443/artifactory/blob-prod/ghz
+ dest: /usr/local/bin/ghz
+ mode: 0755
+ when: full_provision
+
- name: Fix kernel commandline for interface naming.
shell: |
sed -i 's/enp0s3/eth0/g' /etc/netplan/50-cloud-init.yaml
diff --git a/lte/gateway/deploy/roles/magma/files/update_mme_config_for_sanity.sh b/lte/gateway/deploy/roles/magma/files/update_mme_config_for_sanity.sh
index e9795ce185a0..669ee0776747 100755
--- a/lte/gateway/deploy/roles/magma/files/update_mme_config_for_sanity.sh
+++ b/lte/gateway/deploy/roles/magma/files/update_mme_config_for_sanity.sh
@@ -87,6 +87,27 @@ function configure_restricted_plmn {
"$mme_config_file"
}
+function configure_blocked_imei {
+ # Remove default blocked imei(s) from MME configuration file
+ sed -i -e '/BLOCKED_IMEI_LIST/{n;N;N;N;N;N;N;N;N;N;N;d}' \
+ "$mme_config_file"
+
+ # Configure blocked imei(s) in MME configuration file
+ blocked_imei_config=(
+ '{ IMEI_TAC="99000482"; SNR="351037" }'
+ '{ IMEI_TAC="99333821"; }'
+ )
+ blocked_imei_cmd_str=""
+ for config in "${blocked_imei_config[@]}"
+ do
+ blocked_imei_cmd_str="$blocked_imei_cmd_str\ \ \ \ \ \ \ \ $config,\n"
+ done
+ blocked_imei_cmd_str=${blocked_imei_cmd_str::-3}
+
+ sed -i -e "/BLOCKED_IMEI_LIST/a $blocked_imei_cmd_str" \
+ "$mme_config_file"
+}
+
function restore_mme_config {
# Restore the MME configuration from the backup configuration file and
# delete the backup configuration file, so that MME will use latest
@@ -108,6 +129,7 @@ if [[ $1 == "modify" ]]; then
configure_multiple_plmn_tac
reduce_mobile_reachability_timer_value
configure_restricted_plmn
+ configure_blocked_imei
elif [[ $1 == "restore" ]]; then
# Restore the MME configuration file from the backup config file
restore_mme_config
diff --git a/lte/gateway/fabfile.py b/lte/gateway/fabfile.py
index 4ea4994d6a2a..cf781b2ccdfe 100644
--- a/lte/gateway/fabfile.py
+++ b/lte/gateway/fabfile.py
@@ -92,7 +92,7 @@ def package(vcs='hg', all_deps="False",
run('mkdir -p ~/magma-deps')
print("Generating lte/setup.py and orc8r/setup.py magma dependency packages")
run('./release/pydep finddep --install-from-repo -b --build-output ~/magma-deps'
- + (' -l ./release/magma.lockfile')
+ + (' -l ./release/magma.lockfile.%s' % os)
+ ' python/setup.py'
+ (' %s/setup.py' % ORC8R_AGW_PYTHON_ROOT))
diff --git a/lte/gateway/python/integ_tests/s1aptests/s1ap_utils.py b/lte/gateway/python/integ_tests/s1aptests/s1ap_utils.py
index 8742377c7f22..3637989a0dc6 100644
--- a/lte/gateway/python/integ_tests/s1aptests/s1ap_utils.py
+++ b/lte/gateway/python/integ_tests/s1aptests/s1ap_utils.py
@@ -552,6 +552,7 @@ class SubscriberUtil(object):
SID_PREFIX = "IMSI00101"
IMSI_LEN = 15
+ MAX_IMEI_LEN = 16
def __init__(self, subscriber_client):
"""
@@ -563,6 +564,8 @@ def __init__(self, subscriber_client):
"""
self._sid_idx = 1
self._ue_id = 1
+ self._imei_idx = 1
+ self._imei_default = 3805468432113170
# Maintain references to UE configs to prevent GC
self._ue_cfgs = []
@@ -580,11 +583,21 @@ def _gen_next_sid(self):
print("Using subscriber IMSI %s" % sid)
return sid
- def _get_s1ap_sub(self, sid):
+ def _generate_imei(self, num_ues=1):
+ """ Generates 16 digit IMEI which includes SVN """
+ imei = str(self._imei_default + self._imei_idx)
+ assert(len(imei) <= self.MAX_IMEI_LEN), "Invalid IMEI length"
+ self._imei_idx += 1
+ print("Using IMEI %s" % imei)
+ return imei
+
+
+ def _get_s1ap_sub(self, sid, imei):
"""
Get the subscriber data in s1aptester format.
Args:
The string representation of the subscriber id
+ and imei
"""
ue_cfg = s1ap_types.ueConfig_t()
ue_cfg.ue_id = self._ue_id
@@ -593,8 +606,8 @@ def _get_s1ap_sub(self, sid):
# cast into a uint8.
for i in range(0, 15):
ue_cfg.imsi[i] = ctypes.c_ubyte(int(sid[4 + i]))
- ue_cfg.imei[i] = ctypes.c_ubyte(int("1"))
- ue_cfg.imei[15] = ctypes.c_ubyte(int("1"))
+ for i in range(0, len(imei)):
+ ue_cfg.imei[i] = ctypes.c_ubyte(int(imei[i]))
ue_cfg.imsiLen = self.IMSI_LEN
self._ue_cfgs.append(ue_cfg)
self._ue_id += 1
@@ -607,7 +620,8 @@ def add_sub(self, num_ues=1):
for _ in range(num_ues):
sid = self._gen_next_sid()
self._subscriber_client.add_subscriber(sid)
- subscribers.append(self._get_s1ap_sub(sid))
+ imei = self._generate_imei()
+ subscribers.append(self._get_s1ap_sub(sid, imei))
self._subscriber_client.wait_for_changes()
return subscribers
@@ -1494,11 +1508,13 @@ def send_SetSessionRules(self, imsi, policy_id, flow_list, qos):
)
)
+
class GTPBridgeUtils:
def __init__(self):
self.magma_utils = MagmadUtil(None)
ret = self.magma_utils.exec_command_output(
- "sudo grep ovs_multi_tunnel /etc/magma/spgw.yml")
+ "sudo grep ovs_multi_tunnel /etc/magma/spgw.yml"
+ )
if "false" in ret:
self.gtp_port_name = "gtp0"
else:
@@ -1507,42 +1523,48 @@ def __init__(self):
def get_gtp_port_no(self) -> Optional[int]:
output = self.magma_utils.exec_command_output(
- "sudo ovsdb-client dump Interface name ofport")
- for line in output.split('\n'):
+ "sudo ovsdb-client dump Interface name ofport"
+ )
+ for line in output.split("\n"):
if self.gtp_port_name in line:
port_info = line.split()
return port_info[1]
def get_proxy_port_no(self) -> Optional[int]:
output = self.magma_utils.exec_command_output(
- "sudo ovsdb-client dump Interface name ofport")
- for line in output.split('\n'):
+ "sudo ovsdb-client dump Interface name ofport"
+ )
+ for line in output.split("\n"):
if self.proxy_port in line:
port_info = line.split()
return port_info[1]
+
# RYU rest API is not able dump flows from non zero table.
# this adds similar API using `ovs-ofctl` cmd
def get_flows(self, table_id) -> []:
output = self.magma_utils.exec_command_output(
- "sudo ovs-ofctl dump-flows gtp_br0 table={}".format(table_id))
- return output.split('\n')
+ "sudo ovs-ofctl dump-flows gtp_br0 table={}".format(table_id)
+ )
+ return output.split("\n")
+
class HaUtil:
def __init__(self):
- self._ha_stub = HaServiceStub(
- get_rpc_channel("spgw_service")
- )
+ self._ha_stub = HaServiceStub(get_rpc_channel("spgw_service"))
def offload_agw(self, imsi, enbID, offloadtype=0):
req = StartAgwOffloadRequest(
- enb_id = enbID,
- enb_offload_type = offloadtype,
- imsi = imsi,
- )
+ enb_id=enbID,
+ enb_offload_type=offloadtype,
+ imsi=imsi,
+ )
try:
self._ha_stub.StartAgwOffload(req)
except grpc.RpcError as e:
print("gRPC failed with %s: %s" % (e.code(), e.details()))
+ return False
+
+ return True
class HeaderEnrichmentUtils:
diff --git a/lte/gateway/python/integ_tests/s1aptests/test_agw_offload_idle_active_ue.py b/lte/gateway/python/integ_tests/s1aptests/test_agw_offload_idle_active_ue.py
index 7032b65552c4..014a6710bd79 100644
--- a/lte/gateway/python/integ_tests/s1aptests/test_agw_offload_idle_active_ue.py
+++ b/lte/gateway/python/integ_tests/s1aptests/test_agw_offload_idle_active_ue.py
@@ -18,8 +18,8 @@
from integ_tests.s1aptests import s1ap_wrapper
from integ_tests.s1aptests.s1ap_utils import HaUtil
-class TestAgwOffloadIdleActiveUe(unittest.TestCase):
+class TestAgwOffloadIdleActiveUe(unittest.TestCase):
def setUp(self):
self._s1ap_wrapper = s1ap_wrapper.TestWrapper()
self._ha_util = HaUtil()
@@ -30,7 +30,8 @@ def tearDown(self):
def test_agw_offload_idle_active_ue(self):
""" Basic attach/detach test with a single UE """
# column is a enb parameter, row is a number of enbs
- # column description: 1.Cell Id, 2.Tac, 3.EnbType, 4.PLMN Id 5. PLMN length
+ # column description:
+ # 1.Cell Id, 2.Tac, 3.EnbType, 4.PLMN Id 5. PLMN length
enb_list = [(1, 1, 1, "00101", 5)]
self._s1ap_wrapper.multiEnbConfig(len(enb_list), enb_list)
@@ -42,21 +43,30 @@ def test_agw_offload_idle_active_ue(self):
self._s1ap_wrapper.configUEDevice(num_ues)
req = self._s1ap_wrapper.ue_req
- print("************************* Running End to End attach for ",
- "UE id ", req.ue_id)
+ print(
+ "************************* Running End to End attach for ",
+ "UE id ",
+ req.ue_id,
+ )
# Now actually complete the attach
self._s1ap_wrapper._s1_util.attach(
- req.ue_id, s1ap_types.tfwCmd.UE_END_TO_END_ATTACH_REQUEST,
+ req.ue_id,
+ s1ap_types.tfwCmd.UE_END_TO_END_ATTACH_REQUEST,
s1ap_types.tfwCmd.UE_ATTACH_ACCEPT_IND,
- s1ap_types.ueAttachAccept_t)
+ s1ap_types.ueAttachAccept_t,
+ )
# Wait on EMM Information from MME
self._s1ap_wrapper._s1_util.receive_emm_info()
- print("************************* Offloading UE at state ECM-CONNECTED")
+ print(
+ "************************* Offloading UE at state ECM-CONNECTED"
+ )
# Send offloading request
- self._ha_util.offload_agw(
- "IMSI" + "".join([str(i) for i in req.imsi]), enb_list[0][0]
+ self.assertTrue(
+ self._ha_util.offload_agw(
+ "IMSI" + "".join([str(i) for i in req.imsi]), enb_list[0][0]
+ )
)
response = self._s1ap_wrapper.s1_util.get_response()
@@ -66,8 +76,10 @@ def test_agw_offload_idle_active_ue(self):
print("************************* Offloading UE at state ECM-IDLE")
# Send offloading request
- self._ha_util.offload_agw(
- "IMSI" + "".join([str(i) for i in req.imsi]), enb_list[0][0]
+ self.assertTrue(
+ self._ha_util.offload_agw(
+ "IMSI" + "".join([str(i) for i in req.imsi]), enb_list[0][0]
+ )
)
response = self._s1ap_wrapper.s1_util.get_response()
@@ -105,11 +117,13 @@ def test_agw_offload_idle_active_ue(self):
print("************************* SLEEPING for 2 sec")
time.sleep(2)
- print("************************* Running UE detach for UE id ",
- req.ue_id)
+ print(
+ "************************* Running UE detach for UE id ", req.ue_id
+ )
# Now detach the UE
self._s1ap_wrapper.s1_util.detach(
- req.ue_id, s1ap_types.ueDetachType_t.UE_NORMAL_DETACH.value, True)
+ req.ue_id, s1ap_types.ueDetachType_t.UE_NORMAL_DETACH.value, True
+ )
if __name__ == "__main__":
diff --git a/lte/gateway/python/integ_tests/s1aptests/test_agw_offload_mixed_idle_active_multiue.py b/lte/gateway/python/integ_tests/s1aptests/test_agw_offload_mixed_idle_active_multiue.py
index 140a269ee17d..a1b3a91c88e4 100644
--- a/lte/gateway/python/integ_tests/s1aptests/test_agw_offload_mixed_idle_active_multiue.py
+++ b/lte/gateway/python/integ_tests/s1aptests/test_agw_offload_mixed_idle_active_multiue.py
@@ -21,8 +21,8 @@
from integ_tests.s1aptests import s1ap_wrapper
from integ_tests.s1aptests.s1ap_utils import HaUtil
-class TestAgwOffloadMixedIdleActiveMultiUe(unittest.TestCase):
+class TestAgwOffloadMixedIdleActiveMultiUe(unittest.TestCase):
def setUp(self):
self._s1ap_wrapper = s1ap_wrapper.TestWrapper()
self._ha_util = HaUtil()
@@ -34,7 +34,8 @@ def test_agw_offload_mixed_idle_active_multiue(self):
""" Basic attach/detach test with a single UE """
num_ues = 100
# column is a enb parameter, row is a number of enbs
- # column description: 1.Cell Id, 2.Tac, 3.EnbType, 4.PLMN Id 5. PLMN length
+ # column description:
+ # 1.Cell Id, 2.Tac, 3.EnbType, 4.PLMN Id 5. PLMN length
enb_list = [(1, 1, 1, "00101", 5)]
self._s1ap_wrapper.multiEnbConfig(len(enb_list), enb_list)
@@ -44,13 +45,18 @@ def test_agw_offload_mixed_idle_active_multiue(self):
ue_ids = []
for _ in range(num_ues):
req = self._s1ap_wrapper.ue_req
- print("************************* Running End to End attach for ",
- "UE id ", req.ue_id)
+ print(
+ "************************* Running End to End attach for ",
+ "UE id ",
+ req.ue_id,
+ )
# Now actually complete the attach
self._s1ap_wrapper._s1_util.attach(
- req.ue_id, s1ap_types.tfwCmd.UE_END_TO_END_ATTACH_REQUEST,
+ req.ue_id,
+ s1ap_types.tfwCmd.UE_END_TO_END_ATTACH_REQUEST,
s1ap_types.tfwCmd.UE_ATTACH_ACCEPT_IND,
- s1ap_types.ueAttachAccept_t)
+ s1ap_types.ueAttachAccept_t,
+ )
# Wait on EMM Information from MME
self._s1ap_wrapper._s1_util.receive_emm_info()
@@ -58,7 +64,7 @@ def test_agw_offload_mixed_idle_active_multiue(self):
# Send UE context release request for half of UEs to move them
# to ECM-IDLE state
- for i in range(math.floor(num_ues/2)):
+ for i in range(math.floor(num_ues / 2)):
ue_cntxt_rel_req = s1ap_types.ueCntxtRelReq_t()
ue_cntxt_rel_req.ue_Id = ue_ids[i]
ue_cntxt_rel_req.cause.causeVal = (
@@ -74,7 +80,7 @@ def test_agw_offload_mixed_idle_active_multiue(self):
print("************************* Send Offload Request to AGW")
# Send offloading request
- self._ha_util.offload_agw(None, enb_list[0][0])
+ self.assertTrue(self._ha_util.offload_agw(None, enb_list[0][0]))
# All UEs should eventually receive Context Release Request
# The first half should get it immediately
@@ -83,13 +89,15 @@ def test_agw_offload_mixed_idle_active_multiue(self):
response = self._s1ap_wrapper.s1_util.get_response()
self.assertIn(
response.msg_type,
- [s1ap_types.tfwCmd.UE_CTX_REL_IND.value,
- s1ap_types.tfwCmd.UE_PAGING_IND.value],
- 'Not a paging or ue context release message'
+ [
+ s1ap_types.tfwCmd.UE_CTX_REL_IND.value,
+ s1ap_types.tfwCmd.UE_PAGING_IND.value,
+ ],
+ "Not a paging or ue context release message",
)
# Send service request as paging response
- for i in range(math.floor(num_ues/2)):
+ for i in range(math.floor(num_ues / 2)):
# Send service request to reconnect UE
# Auto-release should happen
ser_req = s1ap_types.ueserviceReq_t()
@@ -127,10 +135,10 @@ def test_agw_offload_mixed_idle_active_multiue(self):
# Now detach the UEs normally
for ue in ue_ids:
- print("************************* Running UE detach for UE id ",
- ue)
+ print("************************* Running UE detach for UE id ", ue)
self._s1ap_wrapper.s1_util.detach(
- ue, s1ap_types.ueDetachType_t.UE_NORMAL_DETACH.value, True)
+ ue, s1ap_types.ueDetachType_t.UE_NORMAL_DETACH.value, True
+ )
if __name__ == "__main__":
diff --git a/lte/gateway/python/integ_tests/s1aptests/test_imei_restriction_no_imeisv_in_smc.py b/lte/gateway/python/integ_tests/s1aptests/test_imei_restriction_no_imeisv_in_smc.py
new file mode 100644
index 000000000000..a48119cd5faa
--- /dev/null
+++ b/lte/gateway/python/integ_tests/s1aptests/test_imei_restriction_no_imeisv_in_smc.py
@@ -0,0 +1,313 @@
+"""
+Copyright 2020 The Magma Authors.
+
+This source code is licensed under the BSD-style license found in the
+LICENSE file in the root directory of this source tree.
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+
+
+import unittest
+
+import s1ap_types
+import s1ap_wrapper
+import time
+import ctypes
+
+
+class TestImeiRestrictionNoImeisvInSmc(unittest.TestCase):
+ def setUp(self):
+ self._s1ap_wrapper = s1ap_wrapper.TestWrapper()
+
+ def tearDown(self):
+ self._s1ap_wrapper.cleanup()
+
+ def test_imei_restriction_no_imeisv_in_smc(self):
+ """
+ This TC does the following:
+ UE 1:
+ 1. Send security mode complete message without imeisv
+ 2. Receive identity request with id type imeisv
+ 3. Send identity rsp with blocked imeisv
+ 4. Verify attach reject is received with cause(5)
+ IMEI_NOT_ACCEPTED
+ UE 2:
+ 1. Send security mode complete message without imeisv
+ 2. Receive identity request with id type imeisv
+ 3. Send identity rsp with an allowed imeisv
+ 4. Detach the UE
+
+ If this TC is executed individually run
+ test_modify_mme_config_for_sanity.py to add
+ { IMEI="9900048235103723" }
+ under the BLOCKED_IMEI_LIST in mme.conf.template.
+
+ After execution of this TC run test_restore_mme_config_after_sanity.py
+ to restore the old mme.conf.template.
+ """
+ num_ues = 2
+ ue_ids = []
+ self._s1ap_wrapper.configUEDevice(num_ues)
+ for _ in range(num_ues):
+ req = self._s1ap_wrapper.ue_req
+ ue_ids.append(req.ue_id)
+ # Send Attach Request
+ attach_req = s1ap_types.ueAttachRequest_t()
+ sec_ctxt = s1ap_types.TFW_CREATE_NEW_SECURITY_CONTEXT
+ id_type = s1ap_types.TFW_MID_TYPE_IMSI
+ eps_type = s1ap_types.TFW_EPS_ATTACH_TYPE_EPS_ATTACH
+ pdn_type = s1ap_types.pdn_Type()
+ pdn_type.pres = True
+ pdn_type.pdn_type = 1
+ attach_req.ue_Id = ue_ids[0]
+ attach_req.mIdType = id_type
+ attach_req.epsAttachType = eps_type
+ attach_req.useOldSecCtxt = sec_ctxt
+ attach_req.pdnType_pr = pdn_type
+
+ self._s1ap_wrapper._s1_util.issue_cmd(
+ s1ap_types.tfwCmd.UE_ATTACH_REQUEST, attach_req
+ )
+ print(
+ "********************** Sent attach req for UE id ", ue_ids[0],
+ )
+
+ response = self._s1ap_wrapper.s1_util.get_response()
+ self.assertEqual(
+ response.msg_type, s1ap_types.tfwCmd.UE_AUTH_REQ_IND.value
+ )
+ auth_req = response.cast(s1ap_types.ueAuthReqInd_t)
+ print(
+ "********************** Received auth req for UE id",
+ auth_req.ue_Id,
+ )
+
+ # Send Authentication Response
+ auth_res = s1ap_types.ueAuthResp_t()
+ auth_res.ue_Id = ue_ids[0]
+ sqnRecvd = s1ap_types.ueSqnRcvd_t()
+ sqnRecvd.pres = 0
+ auth_res.sqnRcvd = sqnRecvd
+ self._s1ap_wrapper._s1_util.issue_cmd(
+ s1ap_types.tfwCmd.UE_AUTH_RESP, auth_res
+ )
+ print("********************** Sent auth rsp for UE id", ue_ids[0])
+
+ response = self._s1ap_wrapper.s1_util.get_response()
+ self.assertEqual(
+ response.msg_type, s1ap_types.tfwCmd.UE_SEC_MOD_CMD_IND.value
+ )
+ sec_mod_cmd = response.cast(s1ap_types.ueSecModeCmdInd_t)
+ print(
+ "********************** Received security mode cmd for UE id",
+ sec_mod_cmd.ue_Id,
+ )
+
+ # Send Security Mode Complete
+ sec_mode_complete = s1ap_types.ueSecModeComplete_t()
+ sec_mode_complete.ue_Id = ue_ids[0]
+ # Do not include imeisv
+ sec_mode_complete.noImeisv = True
+ self._s1ap_wrapper._s1_util.issue_cmd(
+ s1ap_types.tfwCmd.UE_SEC_MOD_COMPLETE, sec_mode_complete
+ )
+ print(
+ "********************** Sent security mode complete for UE id",
+ ue_ids[0],
+ )
+
+ response = self._s1ap_wrapper.s1_util.get_response()
+ self.assertEqual(
+ response.msg_type, s1ap_types.tfwCmd.UE_IDENTITY_REQ_IND.value
+ )
+ id_req = response.cast(s1ap_types.ueIdentityReqInd_t)
+ print(
+ "********************** Received identity req for UE id",
+ id_req.ue_Id,
+ )
+
+ # Mobile Identity types
+ # IMSI=1, IMEI=2, IMEISV=3, TMSI=4, TMGI=5, GUTI=6
+ identity_resp = s1ap_types.ueIdentityResp_t()
+ identity_resp.ue_Id = ue_ids[0]
+ identity_resp.idType = 3
+ identity_resp.idValPres = True
+ imeisv = "9900048235103723"
+ # Check if the len of imeisv exceeds 16
+ self.assertLessEqual(len(imeisv), 16)
+ for i in range(0, len(imeisv)):
+ identity_resp.idVal[i] = ctypes.c_ubyte(int(imeisv[i]))
+ self._s1ap_wrapper._s1_util.issue_cmd(
+ s1ap_types.tfwCmd.UE_IDENTITY_RESP, identity_resp
+ )
+ print("********************** Sent identity rsp for UE id", ue_ids[0])
+
+ # Receive Attach Reject
+ response = self._s1ap_wrapper.s1_util.get_response()
+ self.assertEqual(
+ response.msg_type, s1ap_types.tfwCmd.UE_ATTACH_REJECT_IND.value
+ )
+ attach_rej = response.cast(s1ap_types.ueAttachRejInd_t)
+ print(
+ "********************** Received attach reject for UE id %d"
+ " with emm cause %d" % (ue_ids[0], attach_rej.cause)
+ )
+
+ # Verify cause
+ self.assertEqual(
+ attach_rej.cause, s1ap_types.TFW_EMM_CAUSE_IMEI_NOT_ACCEPTED
+ )
+
+ # UE Context release
+ response = self._s1ap_wrapper.s1_util.get_response()
+ self.assertEqual(
+ response.msg_type, s1ap_types.tfwCmd.UE_CTX_REL_IND.value
+ )
+ ue_context_rel = response.cast(s1ap_types.ueCntxtRelReq_t)
+ print(
+ "********************** Received UE_CTX_REL_IND for UE id ",
+ ue_context_rel.ue_Id,
+ )
+
+ # Attach the 2nd UE
+ attach_req = s1ap_types.ueAttachRequest_t()
+ sec_ctxt = s1ap_types.TFW_CREATE_NEW_SECURITY_CONTEXT
+ id_type = s1ap_types.TFW_MID_TYPE_IMSI
+ eps_type = s1ap_types.TFW_EPS_ATTACH_TYPE_EPS_ATTACH
+ pdn_type = s1ap_types.pdn_Type()
+ pdn_type.pres = True
+ pdn_type.pdn_type = 1
+ attach_req.ue_Id = ue_ids[1]
+ attach_req.mIdType = id_type
+ attach_req.epsAttachType = eps_type
+ attach_req.useOldSecCtxt = sec_ctxt
+ attach_req.pdnType_pr = pdn_type
+
+ self._s1ap_wrapper._s1_util.issue_cmd(
+ s1ap_types.tfwCmd.UE_ATTACH_REQUEST, attach_req
+ )
+ print(
+ "********************** Sent attach req for UE id ", ue_ids[1],
+ )
+
+ response = self._s1ap_wrapper.s1_util.get_response()
+ self.assertEqual(
+ response.msg_type, s1ap_types.tfwCmd.UE_AUTH_REQ_IND.value
+ )
+ auth_req = response.cast(s1ap_types.ueAuthReqInd_t)
+ print(
+ "********************** Received auth req for UE id",
+ auth_req.ue_Id,
+ )
+ # Send Authentication Response
+ auth_res = s1ap_types.ueAuthResp_t()
+ auth_res.ue_Id = ue_ids[1]
+ sqnRecvd = s1ap_types.ueSqnRcvd_t()
+ sqnRecvd.pres = 0
+ auth_res.sqnRcvd = sqnRecvd
+ self._s1ap_wrapper._s1_util.issue_cmd(
+ s1ap_types.tfwCmd.UE_AUTH_RESP, auth_res
+ )
+ print("********************** Sent auth rsp for UE id", ue_ids[1])
+
+ response = self._s1ap_wrapper.s1_util.get_response()
+ self.assertEqual(
+ response.msg_type, s1ap_types.tfwCmd.UE_SEC_MOD_CMD_IND.value
+ )
+ sec_mod_cmd = response.cast(s1ap_types.ueSecModeCmdInd_t)
+ print(
+ "********************** Received security mode cmd for UE id",
+ sec_mod_cmd.ue_Id,
+ )
+
+ # Send Security Mode Complete
+ sec_mode_complete = s1ap_types.ueSecModeComplete_t()
+ sec_mode_complete.ue_Id = ue_ids[1]
+ # Do not include imeisv
+ sec_mode_complete.noImeisv = True
+ self._s1ap_wrapper._s1_util.issue_cmd(
+ s1ap_types.tfwCmd.UE_SEC_MOD_COMPLETE, sec_mode_complete
+ )
+ print(
+ "********************** Sent security mode complete for UE id",
+ ue_ids[1],
+ )
+
+ response = self._s1ap_wrapper.s1_util.get_response()
+ self.assertEqual(
+ response.msg_type, s1ap_types.tfwCmd.UE_IDENTITY_REQ_IND.value
+ )
+ id_req = response.cast(s1ap_types.ueIdentityReqInd_t)
+ print(
+ "********************** Received identity req for UE id",
+ id_req.ue_Id,
+ )
+ # Send Identity Request
+ id_req = response.cast(s1ap_types.ueIdentityReqInd_t)
+ identity_resp = s1ap_types.ueIdentityResp_t()
+ identity_resp.ue_Id = id_req.ue_Id
+ identity_resp.idType = id_req.idType
+ self._s1ap_wrapper._s1_util.issue_cmd(
+ s1ap_types.tfwCmd.UE_IDENTITY_RESP, identity_resp
+ )
+ print("********************** Sent identity rsp for UE id", ue_ids[1])
+
+ response = self._s1ap_wrapper.s1_util.get_response()
+ self.assertEqual(
+ response.msg_type, s1ap_types.tfwCmd.INT_CTX_SETUP_IND.value
+ )
+
+ response = self._s1ap_wrapper.s1_util.get_response()
+ self.assertEqual(
+ response.msg_type, s1ap_types.tfwCmd.UE_ATTACH_ACCEPT_IND.value
+ )
+ attach_acc = response.cast(s1ap_types.ueAttachAccept_t)
+ print(
+ "********************** Received attach accept for UE id",
+ attach_acc.ue_Id,
+ )
+ # Send Attach Complete
+ attach_complete = s1ap_types.ueAttachComplete_t()
+ attach_complete.ue_Id = ue_ids[1]
+ self._s1ap_wrapper._s1_util.issue_cmd(
+ s1ap_types.tfwCmd.UE_ATTACH_COMPLETE, attach_complete
+ )
+ print(
+ "********************** Sent attach complete for UE id", ue_ids[1],
+ )
+ response = self._s1ap_wrapper.s1_util.get_response()
+ self.assertEqual(
+ response.msg_type, s1ap_types.tfwCmd.UE_EMM_INFORMATION.value
+ )
+
+ print("********************** Sleeping for 0.5 seconds ")
+ time.sleep(0.5)
+ # Now detach the UE
+ print("********************** Running UE detach for UE id ", ue_ids[1])
+ detach_req = s1ap_types.uedetachReq_t()
+ detach_req.ue_Id = ue_ids[1]
+ detach_req.ueDetType = (
+ s1ap_types.ueDetachType_t.UE_SWITCHOFF_DETACH.value
+ )
+ self._s1ap_wrapper._s1_util.issue_cmd(
+ s1ap_types.tfwCmd.UE_DETACH_REQUEST, detach_req
+ )
+ # Wait for UE context release command
+ response = self._s1ap_wrapper.s1_util.get_response()
+ self.assertEqual(
+ response.msg_type, s1ap_types.tfwCmd.UE_CTX_REL_IND.value
+ )
+ ue_context_rel = response.cast(s1ap_types.ueCntxtRelReq_t)
+ print(
+ "********************** Received UE_CTX_REL_IND for UE id ",
+ ue_context_rel.ue_Id,
+ )
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/lte/gateway/python/integ_tests/s1aptests/test_imei_restriction_smc.py b/lte/gateway/python/integ_tests/s1aptests/test_imei_restriction_smc.py
new file mode 100644
index 000000000000..11cbdc5cff33
--- /dev/null
+++ b/lte/gateway/python/integ_tests/s1aptests/test_imei_restriction_smc.py
@@ -0,0 +1,177 @@
+"""
+Copyright 2020 The Magma Authors.
+
+This source code is licensed under the BSD-style license found in the
+LICENSE file in the root directory of this source tree.
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+
+
+import unittest
+
+import s1ap_types
+import s1ap_wrapper
+import time
+import ctypes
+
+
+class TestImeiRestrictionSmc(unittest.TestCase):
+ def setUp(self):
+ self._s1ap_wrapper = s1ap_wrapper.TestWrapper()
+
+ def tearDown(self):
+ self._s1ap_wrapper.cleanup()
+
+ def test_imei_restriction_smc(self):
+ """
+ This TC does the following:
+ 1. Send security mode complete message with a blocked imeisv
+ which is same as the one configured in mme.conf.template
+ 2. Verify that attach reject is received with cause(5)
+ IMEI_NOT_ACCEPTED
+ 3. Attach a 2nd UE with an allowed IMEISV by invoking attach utility
+ function
+ 4. Detach the UE
+
+ If this TC is executed individually run
+ test_modify_mme_config_for_sanity.py to add
+ { IMEI="9900048235103723"}
+ under the BLOCKED_IMEI_LIST in mme.conf.template.
+
+ After execution of this TC run test_restore_mme_config_after_sanity.py
+ to restore the old mme.conf.template.
+ """
+ num_ues = 2
+ ue_ids = []
+ self._s1ap_wrapper.configUEDevice(num_ues)
+ for _ in range(num_ues):
+ req = self._s1ap_wrapper.ue_req
+ ue_ids.append(req.ue_id)
+ # Send Attach Request
+ attach_req = s1ap_types.ueAttachRequest_t()
+ sec_ctxt = s1ap_types.TFW_CREATE_NEW_SECURITY_CONTEXT
+ id_type = s1ap_types.TFW_MID_TYPE_IMSI
+ eps_type = s1ap_types.TFW_EPS_ATTACH_TYPE_EPS_ATTACH
+ pdn_type = s1ap_types.pdn_Type()
+ pdn_type.pres = True
+ pdn_type.pdn_type = 1
+ attach_req.ue_Id = ue_ids[0]
+ attach_req.mIdType = id_type
+ attach_req.epsAttachType = eps_type
+ attach_req.useOldSecCtxt = sec_ctxt
+ attach_req.pdnType_pr = pdn_type
+
+ self._s1ap_wrapper._s1_util.issue_cmd(
+ s1ap_types.tfwCmd.UE_ATTACH_REQUEST, attach_req
+ )
+ print(
+ "********************** Sent attach req for UE id ", ue_ids[0],
+ )
+
+ response = self._s1ap_wrapper.s1_util.get_response()
+ self.assertEqual(
+ response.msg_type, s1ap_types.tfwCmd.UE_AUTH_REQ_IND.value
+ )
+ auth_req = response.cast(s1ap_types.ueAuthReqInd_t)
+ print(
+ "********************** Received auth req for UE id",
+ auth_req.ue_Id,
+ )
+
+ # Send Authentication Response
+ auth_res = s1ap_types.ueAuthResp_t()
+ auth_res.ue_Id = ue_ids[0]
+ sqnRecvd = s1ap_types.ueSqnRcvd_t()
+ sqnRecvd.pres = 0
+ auth_res.sqnRcvd = sqnRecvd
+ self._s1ap_wrapper._s1_util.issue_cmd(
+ s1ap_types.tfwCmd.UE_AUTH_RESP, auth_res
+ )
+ print("********************** Sent auth rsp for UE id", ue_ids[0])
+
+ response = self._s1ap_wrapper.s1_util.get_response()
+ self.assertEqual(
+ response.msg_type, s1ap_types.tfwCmd.UE_SEC_MOD_CMD_IND.value
+ )
+ sec_mod_cmd = response.cast(s1ap_types.ueSecModeCmdInd_t)
+ print(
+ "********************** Received security mode cmd for UE id",
+ sec_mod_cmd.ue_Id,
+ )
+
+ # Send Security Mode Complete
+ sec_mode_complete = s1ap_types.ueSecModeComplete_t()
+ sec_mode_complete.ue_Id = ue_ids[0]
+ sec_mode_complete.imeisv_pres = True
+ imeisv = "9900048235103723"
+ # Check if the len of imeisv exceeds 16
+ self.assertLessEqual(len(imeisv), 16)
+ for i in range(0, len(imeisv)):
+ sec_mode_complete.imeisv[i] = ctypes.c_ubyte(int(imeisv[i]))
+ self._s1ap_wrapper._s1_util.issue_cmd(
+ s1ap_types.tfwCmd.UE_SEC_MOD_COMPLETE, sec_mode_complete
+ )
+ print(
+ "********************** Sent security mode complete for UE id",
+ ue_ids[0],
+ )
+
+ # Receive Attach Reject
+ response = self._s1ap_wrapper.s1_util.get_response()
+ self.assertEqual(
+ response.msg_type, s1ap_types.tfwCmd.UE_ATTACH_REJECT_IND.value
+ )
+ attach_rej = response.cast(s1ap_types.ueAttachRejInd_t)
+ print(
+ "********************** Received attach reject for UE id %d"
+ " with emm cause %d" % (attach_rej.ue_Id, attach_rej.cause)
+ )
+
+ # Verify cause
+ self.assertEqual(
+ attach_rej.cause, s1ap_types.TFW_EMM_CAUSE_IMEI_NOT_ACCEPTED
+ )
+
+ # UE Context release
+ response = self._s1ap_wrapper.s1_util.get_response()
+ self.assertEqual(
+ response.msg_type, s1ap_types.tfwCmd.UE_CTX_REL_IND.value
+ )
+
+ ue_context_rel = response.cast(s1ap_types.ueCntxtRelReq_t)
+ print(
+ "********************** Received UE_CTX_REL_IND for UE id ",
+ ue_context_rel.ue_Id,
+ )
+
+ # Attach the 2nd UE
+ print(
+ "************ Running end-end attach for UE id ************",
+ ue_ids[1],
+ )
+ self._s1ap_wrapper._s1_util.attach(
+ ue_ids[1],
+ s1ap_types.tfwCmd.UE_END_TO_END_ATTACH_REQUEST,
+ s1ap_types.tfwCmd.UE_ATTACH_ACCEPT_IND,
+ s1ap_types.ueAttachAccept_t,
+ )
+
+ # Wait on EMM Information from MME
+ self._s1ap_wrapper._s1_util.receive_emm_info()
+
+ print("********************** Sleeping for 2 seconds")
+ time.sleep(2)
+ print("********************** Running UE detach for UE id ", ue_ids[1])
+ # Now detach the UE
+ self._s1ap_wrapper.s1_util.detach(
+ ue_ids[1], s1ap_types.ueDetachType_t.UE_NORMAL_DETACH.value
+ )
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/lte/gateway/python/integ_tests/s1aptests/test_imei_restriction_wildcard_snr.py b/lte/gateway/python/integ_tests/s1aptests/test_imei_restriction_wildcard_snr.py
new file mode 100644
index 000000000000..13acf4a82af5
--- /dev/null
+++ b/lte/gateway/python/integ_tests/s1aptests/test_imei_restriction_wildcard_snr.py
@@ -0,0 +1,148 @@
+"""
+Copyright 2020 The Magma Authors.
+
+This source code is licensed under the BSD-style license found in the
+LICENSE file in the root directory of this source tree.
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+
+
+import unittest
+
+import s1ap_types
+import s1ap_wrapper
+import ctypes
+
+
+class TestImeiRestrictionWildcardSnr(unittest.TestCase):
+ def setUp(self):
+ self._s1ap_wrapper = s1ap_wrapper.TestWrapper()
+
+ def tearDown(self):
+ self._s1ap_wrapper.cleanup()
+
+ def test_imei_restriction_wildcard_snr(self):
+ """
+ This TC validates imei restriction scenario where only tac
+ part of imei is configured i.e snr is wildcarded:
+ 1. Send security mode complete message with a blocked imeisv
+ where tac is same as the one configured in mme.conf.template
+ 2. Verify that attach reject is received with cause(5)
+ IMEI_NOT_ACCEPTED
+
+ If this TC is executed individually run
+ test_modify_mme_config_for_sanity.py to add
+ { IMEI_TAC="99333821"}
+ under the BLOCKED_IMEI_LIST in mme.conf.template.
+
+ After execution of this TC run test_restore_mme_config_after_sanity.py
+ to restore the old mme.conf.template.
+ """
+ num_ues = 1
+ self._s1ap_wrapper.configUEDevice(num_ues)
+ req = self._s1ap_wrapper.ue_req
+ # Send Attach Request
+ attach_req = s1ap_types.ueAttachRequest_t()
+ sec_ctxt = s1ap_types.TFW_CREATE_NEW_SECURITY_CONTEXT
+ id_type = s1ap_types.TFW_MID_TYPE_IMSI
+ eps_type = s1ap_types.TFW_EPS_ATTACH_TYPE_EPS_ATTACH
+ pdn_type = s1ap_types.pdn_Type()
+ pdn_type.pres = True
+ pdn_type.pdn_type = 1
+ attach_req.ue_Id = req.ue_id
+ attach_req.mIdType = id_type
+ attach_req.epsAttachType = eps_type
+ attach_req.useOldSecCtxt = sec_ctxt
+ attach_req.pdnType_pr = pdn_type
+
+ self._s1ap_wrapper._s1_util.issue_cmd(
+ s1ap_types.tfwCmd.UE_ATTACH_REQUEST, attach_req
+ )
+ print(
+ "********************** Sent attach req for UE id ", req.ue_id,
+ )
+
+ response = self._s1ap_wrapper.s1_util.get_response()
+ self.assertEqual(
+ response.msg_type, s1ap_types.tfwCmd.UE_AUTH_REQ_IND.value
+ )
+ auth_req = response.cast(s1ap_types.ueAuthReqInd_t)
+ print(
+ "********************** Received auth req for UE id",
+ auth_req.ue_Id,
+ )
+
+ # Send Authentication Response
+ auth_res = s1ap_types.ueAuthResp_t()
+ auth_res.ue_Id = req.ue_id
+ sqnRecvd = s1ap_types.ueSqnRcvd_t()
+ sqnRecvd.pres = 0
+ auth_res.sqnRcvd = sqnRecvd
+ self._s1ap_wrapper._s1_util.issue_cmd(
+ s1ap_types.tfwCmd.UE_AUTH_RESP, auth_res
+ )
+ print("********************** Sent auth rsp for UE id", req.ue_id)
+
+ response = self._s1ap_wrapper.s1_util.get_response()
+ self.assertEqual(
+ response.msg_type, s1ap_types.tfwCmd.UE_SEC_MOD_CMD_IND.value
+ )
+ sec_mod_cmd = response.cast(s1ap_types.ueSecModeCmdInd_t)
+ print(
+ "********************** Received security mode cmd for UE id",
+ sec_mod_cmd.ue_Id,
+ )
+
+ # Send Security Mode Complete
+ sec_mode_complete = s1ap_types.ueSecModeComplete_t()
+ sec_mode_complete.ue_Id = req.ue_id
+ sec_mode_complete.imeisv_pres = True
+ imeisv = "9933382135103723"
+ # Check if the len of imeisv exceeds 16
+ self.assertLessEqual(len(imeisv), 16)
+ for i in range(0, len(imeisv)):
+ sec_mode_complete.imeisv[i] = ctypes.c_ubyte(int(imeisv[i]))
+ self._s1ap_wrapper._s1_util.issue_cmd(
+ s1ap_types.tfwCmd.UE_SEC_MOD_COMPLETE, sec_mode_complete
+ )
+ print(
+ "********************** Sent security mode complete for UE id",
+ req.ue_id,
+ )
+
+ # Receive Attach Reject
+ response = self._s1ap_wrapper.s1_util.get_response()
+ self.assertEqual(
+ response.msg_type, s1ap_types.tfwCmd.UE_ATTACH_REJECT_IND.value
+ )
+ attach_rej = response.cast(s1ap_types.ueAttachRejInd_t)
+ print(
+ "********************** Received attach reject for UE id %d"
+ " with emm cause %d" % (attach_rej.ue_Id, attach_rej.cause)
+ )
+
+ # Verify cause
+ self.assertEqual(
+ attach_rej.cause, s1ap_types.TFW_EMM_CAUSE_IMEI_NOT_ACCEPTED
+ )
+
+ # UE Context release
+ response = self._s1ap_wrapper.s1_util.get_response()
+ self.assertEqual(
+ response.msg_type, s1ap_types.tfwCmd.UE_CTX_REL_IND.value
+ )
+
+ ue_context_rel = response.cast(s1ap_types.ueCntxtRelReq_t)
+ print(
+ "********************** Received UE_CTX_REL_IND for UE id ",
+ ue_context_rel.ue_Id,
+ )
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/lte/gateway/python/integ_tests/s1aptests/test_ipv4v6_secondary_pdn_with_ded_bearer.py b/lte/gateway/python/integ_tests/s1aptests/test_ipv4v6_secondary_pdn_with_ded_bearer.py
index 3dc0281b0939..d5127d203794 100644
--- a/lte/gateway/python/integ_tests/s1aptests/test_ipv4v6_secondary_pdn_with_ded_bearer.py
+++ b/lte/gateway/python/integ_tests/s1aptests/test_ipv4v6_secondary_pdn_with_ded_bearer.py
@@ -173,7 +173,11 @@ def test_ipv4v6_secondary_pdn_with_ded_bearer(self):
print(
"********************** Added default bearer for apn-%s,"
" bearer id-%d, pdn type-%d"
- % (apn, act_def_bearer_req.m.pdnInfo.epsBearerId, pdn_type,)
+ % (
+ apn,
+ act_def_bearer_req.m.pdnInfo.epsBearerId,
+ pdn_type,
+ )
)
# Receive Router Advertisement message
@@ -202,7 +206,7 @@ def test_ipv4v6_secondary_pdn_with_ded_bearer(self):
"********************** Sending RAR for IMSI",
"".join([str(i) for i in req.imsi]),
)
- self._sessionManager_util.create_ReAuthRequest(
+ self._sessionManager_util.send_ReAuthRequest(
"IMSI" + "".join([str(i) for i in req.imsi]),
policy_id,
flow_list,
diff --git a/lte/gateway/python/integ_tests/s1aptests/test_ipv4v6_secondary_pdn_with_ded_bearer_multi_ue.py b/lte/gateway/python/integ_tests/s1aptests/test_ipv4v6_secondary_pdn_with_ded_bearer_multi_ue.py
index 1458c91a1479..faf798fcacda 100644
--- a/lte/gateway/python/integ_tests/s1aptests/test_ipv4v6_secondary_pdn_with_ded_bearer_multi_ue.py
+++ b/lte/gateway/python/integ_tests/s1aptests/test_ipv4v6_secondary_pdn_with_ded_bearer_multi_ue.py
@@ -25,7 +25,7 @@ def tearDown(self):
self._s1ap_wrapper.cleanup()
def test_ipv4v6_secondary_pdn_with_ded_bearer_multi_ue(self):
- """ Attach a single UE + add a secondary pdn with
+ """Attach a single UE + add a secondary pdn with
IPv4v6 + add dedicated bearer + detach
Repeat for 4 UEs"""
num_ues = 4
@@ -179,7 +179,11 @@ def test_ipv4v6_secondary_pdn_with_ded_bearer_multi_ue(self):
print(
"********************** Added default bearer for apn-%s,"
" bearer id-%d, pdn type-%d"
- % (apn, act_def_bearer_req.m.pdnInfo.epsBearerId, pdn_type,)
+ % (
+ apn,
+ act_def_bearer_req.m.pdnInfo.epsBearerId,
+ pdn_type,
+ )
)
# Receive Router Advertisement message
@@ -208,7 +212,7 @@ def test_ipv4v6_secondary_pdn_with_ded_bearer_multi_ue(self):
"********************** Sending RAR for IMSI",
"".join([str(i) for i in req.imsi]),
)
- self._sessionManager_util.create_ReAuthRequest(
+ self._sessionManager_util.send_ReAuthRequest(
"IMSI" + "".join([str(i) for i in req.imsi]),
policy_id,
flow_list,
diff --git a/lte/gateway/python/integ_tests/s1aptests/test_ipv6_secondary_pdn_with_ded_bearer.py b/lte/gateway/python/integ_tests/s1aptests/test_ipv6_secondary_pdn_with_ded_bearer.py
index 113a927e7428..60c418549022 100644
--- a/lte/gateway/python/integ_tests/s1aptests/test_ipv6_secondary_pdn_with_ded_bearer.py
+++ b/lte/gateway/python/integ_tests/s1aptests/test_ipv6_secondary_pdn_with_ded_bearer.py
@@ -149,7 +149,11 @@ def test_ipv6_secondary_pdn_with_ded_bearer(self):
print(
"********************** Added default bearer for apn-%s,"
" bearer id-%d, pdn type-%d"
- % (apn, act_def_bearer_req.m.pdnInfo.epsBearerId, pdn_type,)
+ % (
+ apn,
+ act_def_bearer_req.m.pdnInfo.epsBearerId,
+ pdn_type,
+ )
)
# Receive Router Advertisement message
@@ -178,7 +182,7 @@ def test_ipv6_secondary_pdn_with_ded_bearer(self):
"********************** Sending RAR for IMSI",
"".join([str(i) for i in req.imsi]),
)
- self._sessionManager_util.create_ReAuthRequest(
+ self._sessionManager_util.send_ReAuthRequest(
"IMSI" + "".join([str(i) for i in req.imsi]),
policy_id,
flow_list,
diff --git a/lte/gateway/python/integ_tests/s1aptests/test_outoforder_erab_setup_rsp_dedicated_bearer.py b/lte/gateway/python/integ_tests/s1aptests/test_outoforder_erab_setup_rsp_dedicated_bearer.py
index 527962f8578b..963d4c34651a 100755
--- a/lte/gateway/python/integ_tests/s1aptests/test_outoforder_erab_setup_rsp_dedicated_bearer.py
+++ b/lte/gateway/python/integ_tests/s1aptests/test_outoforder_erab_setup_rsp_dedicated_bearer.py
@@ -30,7 +30,7 @@ def tearDown(self):
self._s1ap_wrapper.cleanup()
def test_outoforder_erab_setup_rsp_dedicated_bearer(self):
- """ Attach a single UE + add dedicated bearer + send erab setup rsp
+ """Attach a single UE + add dedicated bearer + send erab setup rsp
message out of order for the dedicated bearer"""
num_ue = 1
@@ -168,7 +168,7 @@ def test_outoforder_erab_setup_rsp_dedicated_bearer(self):
"********************** Sending RAR for IMSI",
"".join([str(i) for i in req.imsi]),
)
- self._sessionManager_util.create_ReAuthRequest(
+ self._sessionManager_util.send_ReAuthRequest(
"IMSI" + "".join([str(i) for i in req.imsi]),
policy_id,
flow_list,
diff --git a/lte/gateway/python/magma/enodebd/data_models/data_model.py b/lte/gateway/python/magma/enodebd/data_models/data_model.py
index 2e0aaf6aa656..1c0db10d9a99 100644
--- a/lte/gateway/python/magma/enodebd/data_models/data_model.py
+++ b/lte/gateway/python/magma/enodebd/data_models/data_model.py
@@ -13,7 +13,8 @@
from abc import ABC, abstractmethod
from collections import namedtuple
-from typing import List, Dict, Any, Callable, Optional
+from typing import Any, Callable, Dict, List, Optional
+
from magma.enodebd.data_models.data_model_parameters import ParameterName
TrParam = namedtuple('TrParam', ['path', 'is_invasive', 'type', 'is_optional'])
diff --git a/lte/gateway/python/magma/enodebd/data_models/transform_for_magma.py b/lte/gateway/python/magma/enodebd/data_models/transform_for_magma.py
index 0ba156536155..7550c2a052db 100644
--- a/lte/gateway/python/magma/enodebd/data_models/transform_for_magma.py
+++ b/lte/gateway/python/magma/enodebd/data_models/transform_for_magma.py
@@ -10,11 +10,11 @@
See the License for the specific language governing permissions and
limitations under the License.
"""
-from magma.enodebd.logger import EnodebdLogger as logger
import textwrap
from typing import Optional, Union
-from magma.enodebd.exceptions import ConfigurationError
+from magma.enodebd.exceptions import ConfigurationError
+from magma.enodebd.logger import EnodebdLogger as logger
DUPLEX_MAP = {
'01': 'TDDMode',
diff --git a/lte/gateway/python/magma/enodebd/device_config/configuration_init.py b/lte/gateway/python/magma/enodebd/device_config/configuration_init.py
index a847504b82d4..15cc9743ae9a 100644
--- a/lte/gateway/python/magma/enodebd/device_config/configuration_init.py
+++ b/lte/gateway/python/magma/enodebd/device_config/configuration_init.py
@@ -12,23 +12,24 @@
"""
import json
-from magma.enodebd.logger import EnodebdLogger as logger
from collections import namedtuple
-from lte.protos.mconfig import mconfigs_pb2
from typing import Any, Optional, Union
+
+from lte.protos.mconfig import mconfigs_pb2
from magma.common.misc_utils import get_ip_from_if
+from magma.configuration.exceptions import LoadConfigError
+from magma.configuration.mconfig_managers import load_service_mconfig_as_json
from magma.enodebd.data_models.data_model import DataModel
+from magma.enodebd.data_models.data_model_parameters import ParameterName
from magma.enodebd.device_config.enodeb_config_postprocessor import \
EnodebConfigurationPostProcessor
from magma.enodebd.device_config.enodeb_configuration import \
EnodebConfiguration
-from magma.enodebd.data_models.data_model_parameters import ParameterName
from magma.enodebd.exceptions import ConfigurationError
-from magma.enodebd.lte_utils import DuplexMode, \
- map_earfcndl_to_duplex_mode, map_earfcndl_to_band_earfcnul_mode
-from magma.configuration.exceptions import LoadConfigError
-from magma.configuration.mconfig_managers import load_service_mconfig_as_json
-
+from magma.enodebd.logger import EnodebdLogger as logger
+from magma.enodebd.lte_utils import (DuplexMode,
+ map_earfcndl_to_band_earfcnul_mode,
+ map_earfcndl_to_duplex_mode)
# LTE constants
DEFAULT_S1_PORT = 36412
diff --git a/lte/gateway/python/magma/enodebd/device_config/enodeb_config_postprocessor.py b/lte/gateway/python/magma/enodebd/device_config/enodeb_config_postprocessor.py
index 788553f5fd87..b650d230f842 100644
--- a/lte/gateway/python/magma/enodebd/device_config/enodeb_config_postprocessor.py
+++ b/lte/gateway/python/magma/enodebd/device_config/enodeb_config_postprocessor.py
@@ -10,7 +10,8 @@
See the License for the specific language governing permissions and
limitations under the License.
"""
-from abc import abstractmethod, ABC
+from abc import ABC, abstractmethod
+
from magma.enodebd.device_config.enodeb_configuration import \
EnodebConfiguration
diff --git a/lte/gateway/python/magma/enodebd/device_config/enodeb_configuration.py b/lte/gateway/python/magma/enodebd/device_config/enodeb_configuration.py
index 709766950ebe..fe6c8b49cd0d 100644
--- a/lte/gateway/python/magma/enodebd/device_config/enodeb_configuration.py
+++ b/lte/gateway/python/magma/enodebd/device_config/enodeb_configuration.py
@@ -12,11 +12,12 @@
"""
import json
-from magma.enodebd.logger import EnodebdLogger as logger
-from typing import List, Any
+from typing import Any, List
+
+from magma.enodebd.data_models.data_model import DataModel
from magma.enodebd.data_models.data_model_parameters import ParameterName
from magma.enodebd.exceptions import ConfigurationError
-from magma.enodebd.data_models.data_model import DataModel
+from magma.enodebd.logger import EnodebdLogger as logger
class EnodebConfiguration():
diff --git a/lte/gateway/python/magma/enodebd/devices/baicells.py b/lte/gateway/python/magma/enodebd/devices/baicells.py
index ff6b995e279c..1e83ffde0ce7 100644
--- a/lte/gateway/python/magma/enodebd/devices/baicells.py
+++ b/lte/gateway/python/magma/enodebd/devices/baicells.py
@@ -16,8 +16,8 @@
from magma.common.service import MagmaService
from magma.enodebd.data_models import transform_for_enb, transform_for_magma
from magma.enodebd.data_models.data_model import DataModel, TrParam
-from magma.enodebd.data_models.data_model_parameters import ParameterName, \
- TrParameterType
+from magma.enodebd.data_models.data_model_parameters import (ParameterName,
+ TrParameterType)
from magma.enodebd.device_config.enodeb_config_postprocessor import \
EnodebConfigurationPostProcessor
from magma.enodebd.device_config.enodeb_configuration import \
@@ -25,15 +25,26 @@
from magma.enodebd.devices.device_utils import EnodebDeviceName
from magma.enodebd.state_machines.enb_acs_impl import \
BasicEnodebAcsStateMachine
-from magma.enodebd.state_machines.enb_acs_states import AddObjectsState, \
- BaicellsRemWaitState, BaicellsSendRebootState, CheckOptionalParamsState, \
- DeleteObjectsState, EndSessionState, EnodebAcsState, ErrorState, \
- GetObjectParametersState, GetParametersState, \
- SendGetTransientParametersState, SetParameterValuesState, \
- WaitEmptyMessageState, WaitGetObjectParametersState, \
- WaitGetParametersState, WaitGetTransientParametersState, \
- WaitInformMRebootState, WaitInformState, WaitRebootResponseState, \
- WaitSetParameterValuesState
+from magma.enodebd.state_machines.enb_acs_states import (AddObjectsState,
+ BaicellsRemWaitState,
+ BaicellsSendRebootState,
+ CheckOptionalParamsState,
+ DeleteObjectsState,
+ EndSessionState,
+ EnodebAcsState,
+ ErrorState,
+ GetObjectParametersState,
+ GetParametersState,
+ SendGetTransientParametersState,
+ SetParameterValuesState,
+ WaitEmptyMessageState,
+ WaitGetObjectParametersState,
+ WaitGetParametersState,
+ WaitGetTransientParametersState,
+ WaitInformMRebootState,
+ WaitInformState,
+ WaitRebootResponseState,
+ WaitSetParameterValuesState)
class BaicellsHandler(BasicEnodebAcsStateMachine):
diff --git a/lte/gateway/python/magma/enodebd/devices/baicells_old.py b/lte/gateway/python/magma/enodebd/devices/baicells_old.py
index a0bf7e6a1ca3..60fd85f37c80 100644
--- a/lte/gateway/python/magma/enodebd/devices/baicells_old.py
+++ b/lte/gateway/python/magma/enodebd/devices/baicells_old.py
@@ -16,8 +16,8 @@
from magma.common.service import MagmaService
from magma.enodebd.data_models import transform_for_enb, transform_for_magma
from magma.enodebd.data_models.data_model import DataModel, TrParam
-from magma.enodebd.data_models.data_model_parameters import ParameterName, \
- TrParameterType
+from magma.enodebd.data_models.data_model_parameters import (ParameterName,
+ TrParameterType)
from magma.enodebd.device_config.enodeb_config_postprocessor import \
EnodebConfigurationPostProcessor
from magma.enodebd.device_config.enodeb_configuration import \
@@ -25,15 +25,26 @@
from magma.enodebd.devices.device_utils import EnodebDeviceName
from magma.enodebd.state_machines.enb_acs_impl import \
BasicEnodebAcsStateMachine
-from magma.enodebd.state_machines.enb_acs_states import AddObjectsState, \
- BaicellsRemWaitState, BaicellsSendRebootState, CheckOptionalParamsState, \
- DeleteObjectsState, EndSessionState, EnodebAcsState, ErrorState, \
- GetObjectParametersState, GetParametersState, \
- SendGetTransientParametersState, SetParameterValuesState, \
- WaitEmptyMessageState, WaitGetObjectParametersState, \
- WaitGetParametersState, WaitGetTransientParametersState, \
- WaitInformMRebootState, WaitInformState, WaitRebootResponseState, \
- WaitSetParameterValuesState
+from magma.enodebd.state_machines.enb_acs_states import (AddObjectsState,
+ BaicellsRemWaitState,
+ BaicellsSendRebootState,
+ CheckOptionalParamsState,
+ DeleteObjectsState,
+ EndSessionState,
+ EnodebAcsState,
+ ErrorState,
+ GetObjectParametersState,
+ GetParametersState,
+ SendGetTransientParametersState,
+ SetParameterValuesState,
+ WaitEmptyMessageState,
+ WaitGetObjectParametersState,
+ WaitGetParametersState,
+ WaitGetTransientParametersState,
+ WaitInformMRebootState,
+ WaitInformState,
+ WaitRebootResponseState,
+ WaitSetParameterValuesState)
class BaicellsOldHandler(BasicEnodebAcsStateMachine):
diff --git a/lte/gateway/python/magma/enodebd/devices/baicells_qafa.py b/lte/gateway/python/magma/enodebd/devices/baicells_qafa.py
index 5baacb0a425a..f8ced87b0600 100644
--- a/lte/gateway/python/magma/enodebd/devices/baicells_qafa.py
+++ b/lte/gateway/python/magma/enodebd/devices/baicells_qafa.py
@@ -16,24 +16,33 @@
from magma.common.service import MagmaService
from magma.enodebd.data_models import transform_for_enb, transform_for_magma
from magma.enodebd.data_models.data_model import DataModel, TrParam
-from magma.enodebd.data_models.data_model_parameters import ParameterName, \
- TrParameterType
+from magma.enodebd.data_models.data_model_parameters import (ParameterName,
+ TrParameterType)
from magma.enodebd.device_config.enodeb_config_postprocessor import \
EnodebConfigurationPostProcessor
from magma.enodebd.device_config.enodeb_configuration import \
EnodebConfiguration
-from magma.enodebd.devices.baicells_qafb import \
- BaicellsQafbGetObjectParametersState, \
- BaicellsQafbWaitGetTransientParametersState
+from magma.enodebd.devices.baicells_qafb import (BaicellsQafbGetObjectParametersState,
+ BaicellsQafbWaitGetTransientParametersState)
from magma.enodebd.devices.device_utils import EnodebDeviceName
from magma.enodebd.state_machines.enb_acs_impl import \
BasicEnodebAcsStateMachine
-from magma.enodebd.state_machines.enb_acs_states import AddObjectsState, \
- BaicellsSendRebootState, DeleteObjectsState, EndSessionState, \
- EnodebAcsState, ErrorState, GetParametersState, GetRPCMethodsState, \
- SendGetTransientParametersState, SetParameterValuesState, \
- WaitEmptyMessageState, WaitGetParametersState, WaitInformMRebootState, \
- WaitInformState, WaitRebootResponseState, WaitSetParameterValuesState
+from magma.enodebd.state_machines.enb_acs_states import (AddObjectsState,
+ BaicellsSendRebootState,
+ DeleteObjectsState,
+ EndSessionState,
+ EnodebAcsState,
+ ErrorState,
+ GetParametersState,
+ GetRPCMethodsState,
+ SendGetTransientParametersState,
+ SetParameterValuesState,
+ WaitEmptyMessageState,
+ WaitGetParametersState,
+ WaitInformMRebootState,
+ WaitInformState,
+ WaitRebootResponseState,
+ WaitSetParameterValuesState)
class BaicellsQAFAHandler(BasicEnodebAcsStateMachine):
diff --git a/lte/gateway/python/magma/enodebd/devices/baicells_qafb.py b/lte/gateway/python/magma/enodebd/devices/baicells_qafb.py
index 01e0e3141055..a1c967c9c322 100644
--- a/lte/gateway/python/magma/enodebd/devices/baicells_qafb.py
+++ b/lte/gateway/python/magma/enodebd/devices/baicells_qafb.py
@@ -16,8 +16,8 @@
from magma.common.service import MagmaService
from magma.enodebd.data_models import transform_for_enb, transform_for_magma
from magma.enodebd.data_models.data_model import DataModel, TrParam
-from magma.enodebd.data_models.data_model_parameters import ParameterName, \
- TrParameterType
+from magma.enodebd.data_models.data_model_parameters import (ParameterName,
+ TrParameterType)
from magma.enodebd.device_config.configuration_init import build_desired_config
from magma.enodebd.device_config.enodeb_config_postprocessor import \
EnodebConfigurationPostProcessor
@@ -25,20 +25,32 @@
EnodebConfiguration
from magma.enodebd.devices.device_utils import EnodebDeviceName
from magma.enodebd.logger import EnodebdLogger as logger
-from magma.enodebd.state_machines.acs_state_utils import \
- get_all_objects_to_add, get_all_objects_to_delete, \
- get_all_param_values_to_set, get_params_to_get, \
- parse_get_parameter_values_response
+from magma.enodebd.state_machines.acs_state_utils import (get_all_objects_to_add,
+ get_all_objects_to_delete,
+ get_all_param_values_to_set,
+ get_params_to_get,
+ parse_get_parameter_values_response)
from magma.enodebd.state_machines.enb_acs import EnodebAcsStateMachine
from magma.enodebd.state_machines.enb_acs_impl import \
BasicEnodebAcsStateMachine
-from magma.enodebd.state_machines.enb_acs_states import AcsMsgAndTransition, \
- AcsReadMsgResult, AddObjectsState, BaicellsSendRebootState, \
- DeleteObjectsState, EndSessionState, EnodebAcsState, ErrorState, \
- GetParametersState, GetRPCMethodsState, SendGetTransientParametersState, \
- SetParameterValuesState, WaitEmptyMessageState, WaitGetParametersState, \
- WaitInformMRebootState, WaitInformState, WaitRebootResponseState, \
- WaitSetParameterValuesState
+from magma.enodebd.state_machines.enb_acs_states import (AcsMsgAndTransition,
+ AcsReadMsgResult,
+ AddObjectsState,
+ BaicellsSendRebootState,
+ DeleteObjectsState,
+ EndSessionState,
+ EnodebAcsState,
+ ErrorState,
+ GetParametersState,
+ GetRPCMethodsState,
+ SendGetTransientParametersState,
+ SetParameterValuesState,
+ WaitEmptyMessageState,
+ WaitGetParametersState,
+ WaitInformMRebootState,
+ WaitInformState,
+ WaitRebootResponseState,
+ WaitSetParameterValuesState)
from magma.enodebd.tr069 import models
diff --git a/lte/gateway/python/magma/enodebd/devices/baicells_rts.py b/lte/gateway/python/magma/enodebd/devices/baicells_rts.py
index 561a7b3d2c2c..bfa0d83e2b9c 100644
--- a/lte/gateway/python/magma/enodebd/devices/baicells_rts.py
+++ b/lte/gateway/python/magma/enodebd/devices/baicells_rts.py
@@ -11,12 +11,13 @@
limitations under the License.
"""
-from typing import Optional, Callable, Any, Dict, List, Type
+from typing import Any, Callable, Dict, List, Optional, Type
+
from magma.common.service import MagmaService
-from magma.enodebd.data_models.data_model import TrParam, DataModel
-from magma.enodebd.data_models.data_model_parameters import ParameterName, \
- TrParameterType
-from magma.enodebd.data_models import transform_for_magma, transform_for_enb
+from magma.enodebd.data_models import transform_for_enb, transform_for_magma
+from magma.enodebd.data_models.data_model import DataModel, TrParam
+from magma.enodebd.data_models.data_model_parameters import (ParameterName,
+ TrParameterType)
from magma.enodebd.device_config.enodeb_config_postprocessor import \
EnodebConfigurationPostProcessor
from magma.enodebd.device_config.enodeb_configuration import \
@@ -24,15 +25,25 @@
from magma.enodebd.devices.device_utils import EnodebDeviceName
from magma.enodebd.state_machines.enb_acs_impl import \
BasicEnodebAcsStateMachine
-from magma.enodebd.state_machines.enb_acs_states import EnodebAcsState, \
- WaitInformState, SendGetTransientParametersState, \
- WaitGetTransientParametersState, GetParametersState, \
- WaitGetParametersState, GetObjectParametersState, \
- WaitGetObjectParametersState, DeleteObjectsState, AddObjectsState, \
- SetParameterValuesState, WaitSetParameterValuesState, \
- BaicellsSendRebootState, WaitRebootResponseState, WaitInformMRebootState, \
- CheckOptionalParamsState, WaitEmptyMessageState, ErrorState, \
- EndSessionState
+from magma.enodebd.state_machines.enb_acs_states import (AddObjectsState,
+ BaicellsSendRebootState,
+ CheckOptionalParamsState,
+ DeleteObjectsState,
+ EndSessionState,
+ EnodebAcsState,
+ ErrorState,
+ GetObjectParametersState,
+ GetParametersState,
+ SendGetTransientParametersState,
+ SetParameterValuesState,
+ WaitEmptyMessageState,
+ WaitGetObjectParametersState,
+ WaitGetParametersState,
+ WaitGetTransientParametersState,
+ WaitInformMRebootState,
+ WaitInformState,
+ WaitRebootResponseState,
+ WaitSetParameterValuesState)
class BaicellsRTSHandler(BasicEnodebAcsStateMachine):
diff --git a/lte/gateway/python/magma/enodebd/devices/device_map.py b/lte/gateway/python/magma/enodebd/devices/device_map.py
index 0f8d4071c0d8..2167a74d9099 100644
--- a/lte/gateway/python/magma/enodebd/devices/device_map.py
+++ b/lte/gateway/python/magma/enodebd/devices/device_map.py
@@ -12,13 +12,14 @@
"""
from typing import Type
+
from magma.enodebd.devices.baicells import BaicellsHandler
from magma.enodebd.devices.baicells_old import BaicellsOldHandler
from magma.enodebd.devices.baicells_qafa import BaicellsQAFAHandler
from magma.enodebd.devices.baicells_qafb import BaicellsQAFBHandler
from magma.enodebd.devices.baicells_rts import BaicellsRTSHandler
-from magma.enodebd.devices.experimental.cavium import CaviumHandler
from magma.enodebd.devices.device_utils import EnodebDeviceName
+from magma.enodebd.devices.experimental.cavium import CaviumHandler
from magma.enodebd.state_machines.enb_acs import EnodebAcsStateMachine
# This exists only to break a circular dependency. Otherwise there's no
diff --git a/lte/gateway/python/magma/enodebd/devices/device_utils.py b/lte/gateway/python/magma/enodebd/devices/device_utils.py
index cdeef7065d48..8bf50111a713 100644
--- a/lte/gateway/python/magma/enodebd/devices/device_utils.py
+++ b/lte/gateway/python/magma/enodebd/devices/device_utils.py
@@ -11,9 +11,10 @@
limitations under the License.
"""
-from magma.enodebd.logger import EnodebdLogger as logger
import re
+
from magma.enodebd.exceptions import UnrecognizedEnodebError
+from magma.enodebd.logger import EnodebdLogger as logger
class EnodebDeviceName():
diff --git a/lte/gateway/python/magma/enodebd/devices/experimental/cavium.py b/lte/gateway/python/magma/enodebd/devices/experimental/cavium.py
index 48b835d731de..b1b05c0f8755 100644
--- a/lte/gateway/python/magma/enodebd/devices/experimental/cavium.py
+++ b/lte/gateway/python/magma/enodebd/devices/experimental/cavium.py
@@ -16,8 +16,8 @@
from magma.common.service import MagmaService
from magma.enodebd.data_models import transform_for_enb, transform_for_magma
from magma.enodebd.data_models.data_model import DataModel, TrParam
-from magma.enodebd.data_models.data_model_parameters import ParameterName, \
- TrParameterType
+from magma.enodebd.data_models.data_model_parameters import (ParameterName,
+ TrParameterType)
from magma.enodebd.device_config.enodeb_config_postprocessor import \
EnodebConfigurationPostProcessor
from magma.enodebd.device_config.enodeb_configuration import \
@@ -25,19 +25,31 @@
from magma.enodebd.devices.device_utils import EnodebDeviceName
from magma.enodebd.exceptions import Tr069Error
from magma.enodebd.logger import EnodebdLogger as logger
-from magma.enodebd.state_machines.acs_state_utils import \
- get_all_objects_to_add, get_all_objects_to_delete
+from magma.enodebd.state_machines.acs_state_utils import (get_all_objects_to_add,
+ get_all_objects_to_delete)
from magma.enodebd.state_machines.enb_acs import EnodebAcsStateMachine
from magma.enodebd.state_machines.enb_acs_impl import \
BasicEnodebAcsStateMachine
-from magma.enodebd.state_machines.enb_acs_states import AcsMsgAndTransition, \
- AcsReadMsgResult, AddObjectsState, DeleteObjectsState, EndSessionState, \
- EnodebAcsState, ErrorState, GetParametersState, GetRPCMethodsState, \
- SendGetTransientParametersState, SendRebootState, \
- SetParameterValuesNotAdminState, WaitEmptyMessageState, \
- WaitGetObjectParametersState, WaitGetParametersState, \
- WaitGetTransientParametersState, WaitInformMRebootState, WaitInformState, \
- WaitRebootResponseState, WaitSetParameterValuesState
+from magma.enodebd.state_machines.enb_acs_states import (AcsMsgAndTransition,
+ AcsReadMsgResult,
+ AddObjectsState,
+ DeleteObjectsState,
+ EndSessionState,
+ EnodebAcsState,
+ ErrorState,
+ GetParametersState,
+ GetRPCMethodsState,
+ SendGetTransientParametersState,
+ SendRebootState,
+ SetParameterValuesNotAdminState,
+ WaitEmptyMessageState,
+ WaitGetObjectParametersState,
+ WaitGetParametersState,
+ WaitGetTransientParametersState,
+ WaitInformMRebootState,
+ WaitInformState,
+ WaitRebootResponseState,
+ WaitSetParameterValuesState)
from magma.enodebd.tr069 import models
diff --git a/lte/gateway/python/magma/enodebd/enodeb_status.py b/lte/gateway/python/magma/enodebd/enodeb_status.py
index e17a6f9e22d2..f9757f74b897 100644
--- a/lte/gateway/python/magma/enodebd/enodeb_status.py
+++ b/lte/gateway/python/magma/enodebd/enodeb_status.py
@@ -12,24 +12,22 @@
"""
import json
+import os
from collections import namedtuple
from typing import Any, Dict, List, NamedTuple, Optional, Tuple, Union
-import os
from lte.protos.enodebd_pb2 import SingleEnodebStatus
from lte.protos.mconfig import mconfigs_pb2
from magma.common import serialization_utils
from magma.enodebd import metrics
from magma.enodebd.data_models.data_model_parameters import ParameterName
-from magma.enodebd.device_config.configuration_util import \
- get_enb_rf_tx_desired
+from magma.enodebd.device_config.configuration_util import (find_enb_by_cell_id,
+ get_enb_rf_tx_desired)
from magma.enodebd.exceptions import ConfigurationError
from magma.enodebd.logger import EnodebdLogger as logger
-from magma.enodebd.state_machines.enb_acs import EnodebAcsStateMachine
-from magma.enodebd.state_machines.enb_acs_manager import \
- StateMachineManager
from magma.enodebd.s1ap_client import get_all_enb_state
-from magma.enodebd.device_config.configuration_util import find_enb_by_cell_id
+from magma.enodebd.state_machines.enb_acs import EnodebAcsStateMachine
+from magma.enodebd.state_machines.enb_acs_manager import StateMachineManager
from orc8r.protos.service303_pb2 import State
# There are 2 levels of caching for GPS coordinates from the enodeB: module
diff --git a/lte/gateway/python/magma/enodebd/enodebd_iptables_rules.py b/lte/gateway/python/magma/enodebd/enodebd_iptables_rules.py
index 33c71a843cf9..9edd72833b9f 100644
--- a/lte/gateway/python/magma/enodebd/enodebd_iptables_rules.py
+++ b/lte/gateway/python/magma/enodebd/enodebd_iptables_rules.py
@@ -15,17 +15,15 @@
import asyncio
-from magma.enodebd.logger import EnodebdLogger as logger
+import re
import shlex
import subprocess
-import re
from typing import List
-from magma.common.misc_utils import (
- IpPreference,
- get_ip_from_if,
- get_if_ip_with_netmask
-)
+
+from magma.common.misc_utils import (IpPreference, get_if_ip_with_netmask,
+ get_ip_from_if)
from magma.configuration.service_configs import load_service_config
+from magma.enodebd.logger import EnodebdLogger as logger
IPTABLES_RULE_FMT = """sudo iptables -t nat
-{add} PREROUTING
diff --git a/lte/gateway/python/magma/enodebd/logger.py b/lte/gateway/python/magma/enodebd/logger.py
index 04e2512827ce..f45519f6e30b 100644
--- a/lte/gateway/python/magma/enodebd/logger.py
+++ b/lte/gateway/python/magma/enodebd/logger.py
@@ -14,7 +14,6 @@
import logging
from logging.handlers import RotatingFileHandler
-
LOG_FILE = 'var/log/enodebd.log'
MAX_BYTES = 1024 * 1024 * 10 # 10MB
BACKUP_COUNT = 5 # 10MB, 5 files, 50MB total
diff --git a/lte/gateway/python/magma/enodebd/main.py b/lte/gateway/python/magma/enodebd/main.py
index a662d0eb73ff..abe43bbe052d 100644
--- a/lte/gateway/python/magma/enodebd/main.py
+++ b/lte/gateway/python/magma/enodebd/main.py
@@ -15,19 +15,19 @@
from typing import List
from unittest import mock
-from magma.enodebd.enodeb_status import get_service_status_old, \
- get_operational_states
+from lte.protos.mconfig import mconfigs_pb2
from magma.common.sentry import sentry_init
-from magma.enodebd.state_machines.enb_acs_manager import StateMachineManager
+from magma.common.service import MagmaService
+from magma.enodebd.enodeb_status import (get_operational_states,
+ get_service_status_old)
from magma.enodebd.logger import EnodebdLogger as logger
+from magma.enodebd.state_machines.enb_acs_manager import StateMachineManager
+from orc8r.protos.service303_pb2 import State
+
+from .enodebd_iptables_rules import set_enodebd_iptables_rule
from .rpc_servicer import EnodebdRpcServicer
from .stats_manager import StatsManager
from .tr069.server import tr069_server
-from .enodebd_iptables_rules import set_enodebd_iptables_rule
-from magma.common.service import MagmaService
-from orc8r.protos.service303_pb2 import State
-from lte.protos.mconfig import mconfigs_pb2
-
def get_context(ip: str):
diff --git a/lte/gateway/python/magma/enodebd/metrics.py b/lte/gateway/python/magma/enodebd/metrics.py
index ba85a568064c..86273ec536dc 100644
--- a/lte/gateway/python/magma/enodebd/metrics.py
+++ b/lte/gateway/python/magma/enodebd/metrics.py
@@ -11,7 +11,7 @@
limitations under the License.
"""
-from prometheus_client import Gauge, Counter
+from prometheus_client import Counter, Gauge
# Gauges for current eNodeB status
STAT_ENODEB_CONNECTED = Gauge('enodeb_mgmt_connected',
diff --git a/lte/gateway/python/magma/enodebd/rpc_servicer.py b/lte/gateway/python/magma/enodebd/rpc_servicer.py
index 0f1d1e5bb5c8..11cd99d273ba 100644
--- a/lte/gateway/python/magma/enodebd/rpc_servicer.py
+++ b/lte/gateway/python/magma/enodebd/rpc_servicer.py
@@ -11,19 +11,20 @@
limitations under the License.
"""
-import grpc
from typing import Any
-from magma.enodebd.enodeb_status import get_service_status, get_single_enb_status
-from lte.protos.enodebd_pb2 import GetParameterResponse
-from lte.protos.enodebd_pb2_grpc import EnodebdServicer, \
- add_EnodebdServicer_to_server
+
+import grpc
+from lte.protos.enodebd_pb2 import (AllEnodebStatus, EnodebIdentity,
+ GetParameterRequest, GetParameterResponse,
+ SetParameterRequest, SingleEnodebStatus)
+from lte.protos.enodebd_pb2_grpc import (EnodebdServicer,
+ add_EnodebdServicer_to_server)
+from magma.common.rpc_utils import return_void
+from magma.enodebd.enodeb_status import (get_service_status,
+ get_single_enb_status)
from magma.enodebd.state_machines.enb_acs import EnodebAcsStateMachine
+from magma.enodebd.state_machines.enb_acs_manager import StateMachineManager
from orc8r.protos.service303_pb2 import ServiceStatus
-from magma.common.rpc_utils import return_void
-from magma.enodebd.state_machines.enb_acs_manager import \
- StateMachineManager
-from lte.protos.enodebd_pb2 import GetParameterRequest, SetParameterRequest, \
- EnodebIdentity, AllEnodebStatus, SingleEnodebStatus
class EnodebdRpcServicer(EnodebdServicer):
diff --git a/lte/gateway/python/magma/enodebd/s1ap_client.py b/lte/gateway/python/magma/enodebd/s1ap_client.py
index 3dd375fb746a..80f678f8953b 100644
--- a/lte/gateway/python/magma/enodebd/s1ap_client.py
+++ b/lte/gateway/python/magma/enodebd/s1ap_client.py
@@ -13,11 +13,10 @@
from typing import Dict, Optional
import grpc
-
-from magma.common.service_registry import ServiceRegistry
-from orc8r.protos.common_pb2 import Void
from lte.protos.s1ap_service_pb2_grpc import S1apServiceStub
+from magma.common.service_registry import ServiceRegistry
from magma.enodebd.logger import EnodebdLogger as logger
+from orc8r.protos.common_pb2 import Void
S1AP_SERVICE_NAME = "s1ap_service"
DEFAULT_GRPC_TIMEOUT = 20
@@ -43,4 +42,3 @@ def get_all_enb_state() -> Optional[Dict[int, int]]:
err.code(),
err.details())
return {}
-
diff --git a/lte/gateway/python/magma/enodebd/state_machines/acs_state_utils.py b/lte/gateway/python/magma/enodebd/state_machines/acs_state_utils.py
index 28a03971ada1..d4f85033f19c 100644
--- a/lte/gateway/python/magma/enodebd/state_machines/acs_state_utils.py
+++ b/lte/gateway/python/magma/enodebd/state_machines/acs_state_utils.py
@@ -11,15 +11,16 @@
limitations under the License.
"""
-from magma.enodebd.logger import EnodebdLogger as logger
-from typing import Any, Optional, Dict, List
+from typing import Any, Dict, List, Optional
+
from magma.enodebd.data_models.data_model import DataModel
from magma.enodebd.data_models.data_model_parameters import ParameterName
from magma.enodebd.device_config.enodeb_configuration import \
EnodebConfiguration
-from magma.enodebd.devices.device_utils import get_device_name, \
- EnodebDeviceName
+from magma.enodebd.devices.device_utils import (EnodebDeviceName,
+ get_device_name)
from magma.enodebd.exceptions import ConfigurationError
+from magma.enodebd.logger import EnodebdLogger as logger
from magma.enodebd.tr069 import models
diff --git a/lte/gateway/python/magma/enodebd/state_machines/enb_acs.py b/lte/gateway/python/magma/enodebd/state_machines/enb_acs.py
index 10778fc7bd9d..c790158dfd23 100644
--- a/lte/gateway/python/magma/enodebd/state_machines/enb_acs.py
+++ b/lte/gateway/python/magma/enodebd/state_machines/enb_acs.py
@@ -10,9 +10,10 @@
See the License for the specific language governing permissions and
limitations under the License.
"""
-from asyncio import BaseEventLoop
-from typing import Type, Any
from abc import ABC, abstractmethod
+from asyncio import BaseEventLoop
+from typing import Any, Type
+
from magma.common.service import MagmaService
from magma.enodebd.data_models.data_model import DataModel
from magma.enodebd.data_models.data_model_parameters import ParameterName
@@ -195,4 +196,3 @@ def is_enodeb_connected(self) -> bool:
@abstractmethod
def stop_state_machine(self) -> None:
pass
-
diff --git a/lte/gateway/python/magma/enodebd/state_machines/enb_acs_impl.py b/lte/gateway/python/magma/enodebd/state_machines/enb_acs_impl.py
index 46b874b8fbeb..122cc302bf9f 100644
--- a/lte/gateway/python/magma/enodebd/state_machines/enb_acs_impl.py
+++ b/lte/gateway/python/magma/enodebd/state_machines/enb_acs_impl.py
@@ -12,9 +12,9 @@
"""
import traceback
+from abc import abstractmethod
from typing import Any, Dict
-from abc import abstractmethod
from magma.common.service import MagmaService
from magma.enodebd import metrics
from magma.enodebd.data_models.data_model_parameters import ParameterName
diff --git a/lte/gateway/python/magma/enodebd/state_machines/enb_acs_states.py b/lte/gateway/python/magma/enodebd/state_machines/enb_acs_states.py
index 24e311e56d55..09ff6c0d9e24 100644
--- a/lte/gateway/python/magma/enodebd/state_machines/enb_acs_states.py
+++ b/lte/gateway/python/magma/enodebd/state_machines/enb_acs_states.py
@@ -11,20 +11,25 @@
limitations under the License.
"""
+from abc import ABC, abstractmethod
from collections import namedtuple
from typing import Any, Optional
-from abc import ABC, abstractmethod
from magma.enodebd.data_models.data_model_parameters import ParameterName
from magma.enodebd.device_config.configuration_init import build_desired_config
from magma.enodebd.exceptions import ConfigurationError, Tr069Error
from magma.enodebd.logger import EnodebdLogger as logger
-from magma.enodebd.state_machines.acs_state_utils import \
- does_inform_have_event, get_all_objects_to_add, get_all_objects_to_delete, \
- get_all_param_values_to_set, get_obj_param_values_to_set, \
- get_object_params_to_get, get_optional_param_to_check, \
- get_param_values_to_set, get_params_to_get, \
- parse_get_parameter_values_response, process_inform_message
+from magma.enodebd.state_machines.acs_state_utils import (does_inform_have_event,
+ get_all_objects_to_add,
+ get_all_objects_to_delete,
+ get_all_param_values_to_set,
+ get_obj_param_values_to_set,
+ get_object_params_to_get,
+ get_optional_param_to_check,
+ get_param_values_to_set,
+ get_params_to_get,
+ parse_get_parameter_values_response,
+ process_inform_message)
from magma.enodebd.state_machines.enb_acs import EnodebAcsStateMachine
from magma.enodebd.state_machines.timer import StateMachineTimer
from magma.enodebd.tr069 import models
diff --git a/lte/gateway/python/magma/enodebd/stats_manager.py b/lte/gateway/python/magma/enodebd/stats_manager.py
index 337b17d871dd..c2b0129be416 100644
--- a/lte/gateway/python/magma/enodebd/stats_manager.py
+++ b/lte/gateway/python/magma/enodebd/stats_manager.py
@@ -12,15 +12,16 @@
"""
import asyncio
-from magma.enodebd.logger import EnodebdLogger as logger
from xml.etree import ElementTree
+
from aiohttp import web
from magma.common.misc_utils import get_ip_from_if
from magma.configuration.service_configs import load_service_config
-from magma.enodebd.enodeb_status import get_enb_status, \
- update_status_metrics
+from magma.enodebd.enodeb_status import get_enb_status, update_status_metrics
+from magma.enodebd.logger import EnodebdLogger as logger
from magma.enodebd.state_machines.enb_acs import EnodebAcsStateMachine
from magma.enodebd.state_machines.enb_acs_manager import StateMachineManager
+
from . import metrics
diff --git a/lte/gateway/python/magma/enodebd/tests/baicells_old_tests.py b/lte/gateway/python/magma/enodebd/tests/baicells_old_tests.py
index 82fe1bf235c2..36cbabd5e87d 100644
--- a/lte/gateway/python/magma/enodebd/tests/baicells_old_tests.py
+++ b/lte/gateway/python/magma/enodebd/tests/baicells_old_tests.py
@@ -13,12 +13,12 @@
# pylint: disable=protected-access
from magma.enodebd.devices.device_utils import EnodebDeviceName
-from magma.enodebd.tr069 import models
-from magma.enodebd.tests.test_utils.tr069_msg_builder import \
- Tr069MessageBuilder
from magma.enodebd.tests.test_utils.enb_acs_builder import \
EnodebAcsStateMachineBuilder
from magma.enodebd.tests.test_utils.enodeb_handler import EnodebHandlerTestCase
+from magma.enodebd.tests.test_utils.tr069_msg_builder import \
+ Tr069MessageBuilder
+from magma.enodebd.tr069 import models
class BaicellsOldHandlerTests(EnodebHandlerTestCase):
diff --git a/lte/gateway/python/magma/enodebd/tests/baicells_qafb_tests.py b/lte/gateway/python/magma/enodebd/tests/baicells_qafb_tests.py
index 32a5de818e2e..9f23a4488ad5 100644
--- a/lte/gateway/python/magma/enodebd/tests/baicells_qafb_tests.py
+++ b/lte/gateway/python/magma/enodebd/tests/baicells_qafb_tests.py
@@ -13,12 +13,12 @@
# pylint: disable=protected-access
from magma.enodebd.devices.device_utils import EnodebDeviceName
-from magma.enodebd.tr069 import models
-from magma.enodebd.tests.test_utils.tr069_msg_builder import \
- Tr069MessageBuilder
from magma.enodebd.tests.test_utils.enb_acs_builder import \
EnodebAcsStateMachineBuilder
from magma.enodebd.tests.test_utils.enodeb_handler import EnodebHandlerTestCase
+from magma.enodebd.tests.test_utils.tr069_msg_builder import \
+ Tr069MessageBuilder
+from magma.enodebd.tr069 import models
class BaicellsQAFBHandlerTests(EnodebHandlerTestCase):
diff --git a/lte/gateway/python/magma/enodebd/tests/cavium_tests.py b/lte/gateway/python/magma/enodebd/tests/cavium_tests.py
index 643dee161337..22d808879675 100644
--- a/lte/gateway/python/magma/enodebd/tests/cavium_tests.py
+++ b/lte/gateway/python/magma/enodebd/tests/cavium_tests.py
@@ -11,15 +11,15 @@
limitations under the License.
"""
+from magma.enodebd.data_models.data_model_parameters import ParameterName
# pylint: disable=protected-access
from magma.enodebd.devices.device_utils import EnodebDeviceName
-from magma.enodebd.data_models.data_model_parameters import ParameterName
-from magma.enodebd.tr069 import models
-from magma.enodebd.tests.test_utils.tr069_msg_builder import \
- Tr069MessageBuilder
from magma.enodebd.tests.test_utils.enb_acs_builder import \
EnodebAcsStateMachineBuilder
from magma.enodebd.tests.test_utils.enodeb_handler import EnodebHandlerTestCase
+from magma.enodebd.tests.test_utils.tr069_msg_builder import \
+ Tr069MessageBuilder
+from magma.enodebd.tr069 import models
class CaviumHandlerTests(EnodebHandlerTestCase):
diff --git a/lte/gateway/python/magma/enodebd/tests/configuration_init_tests.py b/lte/gateway/python/magma/enodebd/tests/configuration_init_tests.py
index c07a70214e29..52513a6e4aa1 100644
--- a/lte/gateway/python/magma/enodebd/tests/configuration_init_tests.py
+++ b/lte/gateway/python/magma/enodebd/tests/configuration_init_tests.py
@@ -13,18 +13,23 @@
# pylint: disable=protected-access
from unittest import TestCase
-from magma.enodebd.devices.baicells import BaicellsTrDataModel
+
from magma.enodebd.data_models.data_model_parameters import ParameterName
-from magma.enodebd.device_config.configuration_init import \
- _set_pci, _set_bandwidth, _set_tdd_subframe_config, \
- _set_management_server, _set_s1_connection, _set_perf_mgmt, \
- _set_misc_static_params, _set_plmnids_tac, \
- _set_earfcn_freq_band_mode, _get_enb_config
+from magma.enodebd.device_config.configuration_init import (_get_enb_config,
+ _set_bandwidth,
+ _set_earfcn_freq_band_mode,
+ _set_management_server,
+ _set_misc_static_params,
+ _set_pci,
+ _set_perf_mgmt,
+ _set_plmnids_tac,
+ _set_s1_connection,
+ _set_tdd_subframe_config)
from magma.enodebd.device_config.enodeb_configuration import \
EnodebConfiguration
+from magma.enodebd.devices.baicells import BaicellsTrDataModel
from magma.enodebd.exceptions import ConfigurationError
-from magma.enodebd.tests.test_utils.config_builder import \
- EnodebConfigBuilder
+from magma.enodebd.tests.test_utils.config_builder import EnodebConfigBuilder
class EnodebConfigurationFactoryTest(TestCase):
diff --git a/lte/gateway/python/magma/enodebd/tests/data_model_tests.py b/lte/gateway/python/magma/enodebd/tests/data_model_tests.py
index 5e2ffb10dd46..1683725b8231 100644
--- a/lte/gateway/python/magma/enodebd/tests/data_model_tests.py
+++ b/lte/gateway/python/magma/enodebd/tests/data_model_tests.py
@@ -14,8 +14,9 @@
# pylint: disable=protected-access
from unittest import TestCase
-from magma.enodebd.devices.baicells import BaicellsTrDataModel
+
from magma.enodebd.data_models.data_model_parameters import ParameterName
+from magma.enodebd.devices.baicells import BaicellsTrDataModel
class BaicellsTrDataModelTest(TestCase):
diff --git a/lte/gateway/python/magma/enodebd/tests/device_utils_tests.py b/lte/gateway/python/magma/enodebd/tests/device_utils_tests.py
index d56af9a1c4c8..78ebfb9f5896 100644
--- a/lte/gateway/python/magma/enodebd/tests/device_utils_tests.py
+++ b/lte/gateway/python/magma/enodebd/tests/device_utils_tests.py
@@ -14,8 +14,10 @@
# pylint: disable=protected-access
from unittest import TestCase
-from magma.enodebd.devices.device_utils import get_device_name, \
- _parse_sw_version, EnodebDeviceName
+
+from magma.enodebd.devices.device_utils import (EnodebDeviceName,
+ _parse_sw_version,
+ get_device_name)
from magma.enodebd.exceptions import UnrecognizedEnodebError
diff --git a/lte/gateway/python/magma/enodebd/tests/enodeb_configuration_tests.py b/lte/gateway/python/magma/enodebd/tests/enodeb_configuration_tests.py
index 597fb945e342..ea77c17485c3 100644
--- a/lte/gateway/python/magma/enodebd/tests/enodeb_configuration_tests.py
+++ b/lte/gateway/python/magma/enodebd/tests/enodeb_configuration_tests.py
@@ -14,10 +14,11 @@
# pylint: disable=protected-access
from unittest import TestCase
-from magma.enodebd.devices.experimental.cavium import CaviumTrDataModel
+
from magma.enodebd.data_models.data_model_parameters import ParameterName
from magma.enodebd.device_config.enodeb_configuration import \
EnodebConfiguration
+from magma.enodebd.devices.experimental.cavium import CaviumTrDataModel
class EnodebConfigurationTest(TestCase):
diff --git a/lte/gateway/python/magma/enodebd/tests/enodeb_status_tests.py b/lte/gateway/python/magma/enodebd/tests/enodeb_status_tests.py
index 67949c0bb9f2..f2a91905174a 100644
--- a/lte/gateway/python/magma/enodebd/tests/enodeb_status_tests.py
+++ b/lte/gateway/python/magma/enodebd/tests/enodeb_status_tests.py
@@ -13,17 +13,19 @@
# pylint: disable=protected-access
from unittest import TestCase
+
from lte.protos.enodebd_pb2 import SingleEnodebStatus
from magma.enodebd.devices.device_utils import EnodebDeviceName
-from magma.enodebd.enodeb_status import get_service_status_old, \
- get_all_enb_status, get_enb_status, get_single_enb_status
+from magma.enodebd.enodeb_status import (get_all_enb_status, get_enb_status,
+ get_service_status_old,
+ get_single_enb_status)
from magma.enodebd.state_machines.enb_acs_manager import StateMachineManager
-from magma.enodebd.tests.test_utils.tr069_msg_builder import \
- Tr069MessageBuilder
from magma.enodebd.tests.test_utils.enb_acs_builder import \
EnodebAcsStateMachineBuilder
from magma.enodebd.tests.test_utils.spyne_builder import \
get_spyne_context_with_ip
+from magma.enodebd.tests.test_utils.tr069_msg_builder import \
+ Tr069MessageBuilder
class EnodebStatusTests(TestCase):
diff --git a/lte/gateway/python/magma/enodebd/tests/stats_manager_tests.py b/lte/gateway/python/magma/enodebd/tests/stats_manager_tests.py
index 176f9ad62fc5..a970c89bd20e 100644
--- a/lte/gateway/python/magma/enodebd/tests/stats_manager_tests.py
+++ b/lte/gateway/python/magma/enodebd/tests/stats_manager_tests.py
@@ -11,19 +11,19 @@
limitations under the License.
"""
-import pkg_resources
from unittest import TestCase, mock
from xml.etree import ElementTree
+
+import pkg_resources
+
from magma.enodebd import metrics
from magma.enodebd.data_models.data_model_parameters import ParameterName
from magma.enodebd.devices.device_utils import EnodebDeviceName
+from magma.enodebd.state_machines.enb_acs_manager import StateMachineManager
from magma.enodebd.stats_manager import StatsManager
+from magma.enodebd.tests.test_utils.config_builder import EnodebConfigBuilder
from magma.enodebd.tests.test_utils.enb_acs_builder import \
EnodebAcsStateMachineBuilder
-from magma.enodebd.state_machines.enb_acs_manager import \
- StateMachineManager
-from magma.enodebd.tests.test_utils.config_builder import \
- EnodebConfigBuilder
class StatsManagerTest(TestCase):
diff --git a/lte/gateway/python/magma/enodebd/tests/test_utils/enb_acs_builder.py b/lte/gateway/python/magma/enodebd/tests/test_utils/enb_acs_builder.py
index 6c75bc2510e2..95044e8a84d2 100644
--- a/lte/gateway/python/magma/enodebd/tests/test_utils/enb_acs_builder.py
+++ b/lte/gateway/python/magma/enodebd/tests/test_utils/enb_acs_builder.py
@@ -13,12 +13,13 @@
import asyncio
from unittest import mock
+
from magma.common.service import MagmaService
from magma.enodebd.devices.device_map import get_device_handler_from_name
from magma.enodebd.devices.device_utils import EnodebDeviceName
from magma.enodebd.state_machines.enb_acs import EnodebAcsStateMachine
-from magma.enodebd.tests.test_utils.config_builder import EnodebConfigBuilder
from magma.enodebd.state_machines.enb_acs_manager import StateMachineManager
+from magma.enodebd.tests.test_utils.config_builder import EnodebConfigBuilder
class EnodebAcsStateMachineBuilder:
diff --git a/lte/gateway/python/magma/enodebd/tests/test_utils/enodeb_handler.py b/lte/gateway/python/magma/enodebd/tests/test_utils/enodeb_handler.py
index 66c1612d1f9c..a48edaf074f0 100644
--- a/lte/gateway/python/magma/enodebd/tests/test_utils/enodeb_handler.py
+++ b/lte/gateway/python/magma/enodebd/tests/test_utils/enodeb_handler.py
@@ -12,6 +12,7 @@
"""
from unittest import TestCase, mock
+
import magma.enodebd.tests.test_utils.mock_functions as enb_mock
diff --git a/lte/gateway/python/magma/enodebd/tests/test_utils/mock_functions.py b/lte/gateway/python/magma/enodebd/tests/test_utils/mock_functions.py
index 5125800e4eea..59fb0c73c21b 100644
--- a/lte/gateway/python/magma/enodebd/tests/test_utils/mock_functions.py
+++ b/lte/gateway/python/magma/enodebd/tests/test_utils/mock_functions.py
@@ -13,7 +13,6 @@
from typing import Any
-
GET_IP_FROM_IF_PATH = \
'magma.enodebd.device_config.configuration_init.get_ip_from_if'
diff --git a/lte/gateway/python/magma/enodebd/tests/test_utils/spyne_builder.py b/lte/gateway/python/magma/enodebd/tests/test_utils/spyne_builder.py
index e7783555fd0d..0717aad3e71c 100644
--- a/lte/gateway/python/magma/enodebd/tests/test_utils/spyne_builder.py
+++ b/lte/gateway/python/magma/enodebd/tests/test_utils/spyne_builder.py
@@ -12,6 +12,7 @@
"""
from unittest import mock
+
from spyne.server.wsgi import WsgiMethodContext
diff --git a/lte/gateway/python/magma/enodebd/tests/test_utils/tr069_msg_builder.py b/lte/gateway/python/magma/enodebd/tests/test_utils/tr069_msg_builder.py
index 0bc8ce39f996..90992b6ebcea 100644
--- a/lte/gateway/python/magma/enodebd/tests/test_utils/tr069_msg_builder.py
+++ b/lte/gateway/python/magma/enodebd/tests/test_utils/tr069_msg_builder.py
@@ -12,6 +12,7 @@
"""
from typing import Any, List, Optional
+
from magma.enodebd.tr069 import models
diff --git a/lte/gateway/python/magma/enodebd/tests/timer_tests.py b/lte/gateway/python/magma/enodebd/tests/timer_tests.py
index 4efaa485c9fd..6e87a541ea26 100644
--- a/lte/gateway/python/magma/enodebd/tests/timer_tests.py
+++ b/lte/gateway/python/magma/enodebd/tests/timer_tests.py
@@ -13,6 +13,7 @@
# pylint: disable=protected-access
from unittest import TestCase
+
from magma.enodebd.state_machines.timer import StateMachineTimer
@@ -23,4 +24,3 @@ def test_is_done(self):
timer_b = StateMachineTimer(600)
self.assertFalse(timer_b.is_done(), 'Timer should not be done')
-
diff --git a/lte/gateway/python/magma/enodebd/tests/transform_for_enb_tests.py b/lte/gateway/python/magma/enodebd/tests/transform_for_enb_tests.py
index 7c401e492c57..cd6e3008bc3c 100644
--- a/lte/gateway/python/magma/enodebd/tests/transform_for_enb_tests.py
+++ b/lte/gateway/python/magma/enodebd/tests/transform_for_enb_tests.py
@@ -13,6 +13,7 @@
# pylint: disable=protected-access
from unittest import TestCase
+
from magma.enodebd.data_models.transform_for_enb import bandwidth
diff --git a/lte/gateway/python/magma/enodebd/tests/transform_for_magma_tests.py b/lte/gateway/python/magma/enodebd/tests/transform_for_magma_tests.py
index 0297d4e5e2f9..5be0617f5d76 100644
--- a/lte/gateway/python/magma/enodebd/tests/transform_for_magma_tests.py
+++ b/lte/gateway/python/magma/enodebd/tests/transform_for_magma_tests.py
@@ -13,7 +13,8 @@
# pylint: disable=protected-access
from unittest import TestCase
-from magma.enodebd.data_models.transform_for_magma import gps_tr181, bandwidth
+
+from magma.enodebd.data_models.transform_for_magma import bandwidth, gps_tr181
from magma.enodebd.exceptions import ConfigurationError
diff --git a/lte/gateway/python/magma/enodebd/tr069/models.py b/lte/gateway/python/magma/enodebd/tr069/models.py
index 8dde13d5b18e..37392212e495 100644
--- a/lte/gateway/python/magma/enodebd/tr069/models.py
+++ b/lte/gateway/python/magma/enodebd/tr069/models.py
@@ -14,8 +14,8 @@
from spyne.model import ComplexModel
from spyne.model.complex import XmlAttribute, XmlData
-from spyne.model.primitive import Boolean, DateTime, Integer, String, \
- UnsignedInteger
+from spyne.model.primitive import (Boolean, DateTime, Integer, String,
+ UnsignedInteger)
from spyne.util.odict import odict
# Namespaces
diff --git a/lte/gateway/python/magma/enodebd/tr069/server.py b/lte/gateway/python/magma/enodebd/tr069/server.py
index 3fa5d9b18a1e..5ee847c87e8a 100644
--- a/lte/gateway/python/magma/enodebd/tr069/server.py
+++ b/lte/gateway/python/magma/enodebd/tr069/server.py
@@ -11,15 +11,17 @@
limitations under the License.
"""
-import _thread
-from magma.enodebd.logger import EnodebdLogger as logger
import socket
-from wsgiref.simple_server import ServerHandler, WSGIRequestHandler, \
- WSGIServer, make_server
-from spyne.server.wsgi import WsgiApplication
+from wsgiref.simple_server import (ServerHandler, WSGIRequestHandler,
+ WSGIServer, make_server)
+
+import _thread
from magma.common.misc_utils import get_ip_from_if
from magma.configuration.service_configs import load_service_config
+from magma.enodebd.logger import EnodebdLogger as logger
from magma.enodebd.state_machines.enb_acs_manager import StateMachineManager
+from spyne.server.wsgi import WsgiApplication
+
from .models import CWMP_NS
from .rpc_methods import AutoConfigServer
from .spyne_mods import Tr069Application, Tr069Soap11
diff --git a/lte/gateway/python/magma/enodebd/tr069/spyne_mods.py b/lte/gateway/python/magma/enodebd/tr069/spyne_mods.py
index 4870a4c976f8..a50f1069b0c3 100644
--- a/lte/gateway/python/magma/enodebd/tr069/spyne_mods.py
+++ b/lte/gateway/python/magma/enodebd/tr069/spyne_mods.py
@@ -20,10 +20,9 @@
3) Minor enhancements for debug-ability
"""
-from magma.enodebd.logger import EnodebdLogger as logger
-
from lxml import etree
+from magma.enodebd.logger import EnodebdLogger as logger
from spyne.application import Application
from spyne.interface._base import Interface
from spyne.protocol.soap import Soap11
diff --git a/lte/gateway/python/magma/enodebd/tr069/tests/models_tests.py b/lte/gateway/python/magma/enodebd/tr069/tests/models_tests.py
index 972cd2c9d607..26d0c70952b4 100644
--- a/lte/gateway/python/magma/enodebd/tr069/tests/models_tests.py
+++ b/lte/gateway/python/magma/enodebd/tr069/tests/models_tests.py
@@ -12,9 +12,8 @@
"""
import unittest
-from spyne import ComplexModelBase
-
from magma.enodebd.tr069.models import DeviceIdStruct
+from spyne import ComplexModelBase
class DeviceIdStructTests(unittest.TestCase):
diff --git a/lte/gateway/python/magma/health/health_service.py b/lte/gateway/python/magma/health/health_service.py
index 0c49f4af4f94..14565ca47563 100644
--- a/lte/gateway/python/magma/health/health_service.py
+++ b/lte/gateway/python/magma/health/health_service.py
@@ -14,18 +14,17 @@
"""
import glob
import ipaddress
-
import math
from os import path
from lte.protos.enodebd_pb2_grpc import EnodebdStub
-from lte.protos.mobilityd_pb2_grpc import MobilityServiceStub
from lte.protos.mobilityd_pb2 import IPAddress
-from orc8r.protos.common_pb2 import Void
+from lte.protos.mobilityd_pb2_grpc import MobilityServiceStub
from magma.common.service_registry import ServiceRegistry
from magma.configuration.mconfig_managers import load_service_mconfig_as_json
-from magma.health.entities import AGWHealthSummary, RegistrationSuccessRate, \
- CoreDumps
+from magma.health.entities import (AGWHealthSummary, CoreDumps,
+ RegistrationSuccessRate)
+from orc8r.protos.common_pb2 import Void
class AGWHealth:
diff --git a/lte/gateway/python/magma/health/main.py b/lte/gateway/python/magma/health/main.py
index 4047538fdb51..12abe582d3dc 100644
--- a/lte/gateway/python/magma/health/main.py
+++ b/lte/gateway/python/magma/health/main.py
@@ -15,7 +15,6 @@
from magma.common.sentry import sentry_init
from magma.common.service import MagmaService
from magma.configuration.service_configs import load_service_config
-
from magma.health.state_recovery import StateRecoveryJob
diff --git a/lte/gateway/python/magma/health/state_recovery.py b/lte/gateway/python/magma/health/state_recovery.py
index aff3245ec23e..b95e1de80e45 100644
--- a/lte/gateway/python/magma/health/state_recovery.py
+++ b/lte/gateway/python/magma/health/state_recovery.py
@@ -10,10 +10,9 @@
See the License for the specific language governing permissions and
limitations under the License.
"""
+import logging
import os
import shutil
-import logging
-
from time import time
from typing import Dict, List, NamedTuple, Optional
@@ -21,7 +20,6 @@
from magma.common.job import Job
from magma.magmad.check import subprocess_workflow
from orc8r.protos.service_status_pb2 import ServiceExitStatus
-
from redis.exceptions import ConnectionError
SystemdServiceParams = NamedTuple('SystemdServiceParams', [('service', str)])
diff --git a/lte/gateway/python/magma/monitord/cpe_monitoring.py b/lte/gateway/python/magma/monitord/cpe_monitoring.py
index 0c7ce36191a8..5d60eef93307 100644
--- a/lte/gateway/python/magma/monitord/cpe_monitoring.py
+++ b/lte/gateway/python/magma/monitord/cpe_monitoring.py
@@ -10,11 +10,11 @@
See the License for the specific language governing permissions and
limitations under the License.
"""
+import ipaddress
import logging
from collections import defaultdict
from time import time
from typing import Dict, List, NamedTuple, Optional
-import ipaddress
import grpc
from lte.protos.mobilityd_pb2 import IPAddress, SubscriberIPTable
diff --git a/lte/gateway/python/magma/monitord/icmp_monitoring.py b/lte/gateway/python/magma/monitord/icmp_monitoring.py
index 19e70e21ccd9..db562b3e9f9c 100644
--- a/lte/gateway/python/magma/monitord/icmp_monitoring.py
+++ b/lte/gateway/python/magma/monitord/icmp_monitoring.py
@@ -15,9 +15,9 @@
from typing import Dict, List, Optional
from magma.common.job import Job
-from magma.magmad.check.network_check.ping import PingInterfaceCommandParams, \
- ping_interface_async
-from magma.magmad.check.network_check.ping import PingCommandResult
+from magma.magmad.check.network_check.ping import (PingCommandResult,
+ PingInterfaceCommandParams,
+ ping_interface_async)
NUM_PACKETS = 4
DEFAULT_POLLING_INTERVAL = 60
diff --git a/lte/gateway/python/magma/monitord/main.py b/lte/gateway/python/magma/monitord/main.py
index d276c7255cf5..138d1d9eaed2 100644
--- a/lte/gateway/python/magma/monitord/main.py
+++ b/lte/gateway/python/magma/monitord/main.py
@@ -13,14 +13,15 @@
import logging
-from lte.protos.mconfig import mconfigs_pb2
-from magma.common.service import MagmaService
+from lte.protos.mobilityd_pb2 import IPAddress
from magma.common.sentry import sentry_init
+from magma.common.service import MagmaService
from magma.configuration import load_service_config
+from magma.monitord.cpe_monitoring import CpeMonitoringModule
from magma.monitord.icmp_monitoring import ICMPMonitoring
from magma.monitord.icmp_state import serialize_subscriber_states
-from magma.monitord.cpe_monitoring import CpeMonitoringModule
-from lte.protos.mobilityd_pb2 import IPAddress
+
+from lte.protos.mconfig import mconfigs_pb2
def _get_serialized_subscriber_states(cpe_monitor: CpeMonitoringModule):
diff --git a/lte/gateway/python/magma/monitord/tests/test_icmp_monitor.py b/lte/gateway/python/magma/monitord/tests/test_icmp_monitor.py
index 05894f22c47d..0471bac5b947 100644
--- a/lte/gateway/python/magma/monitord/tests/test_icmp_monitor.py
+++ b/lte/gateway/python/magma/monitord/tests/test_icmp_monitor.py
@@ -16,8 +16,8 @@
import unittest
from lte.protos.mobilityd_pb2 import IPAddress, SubscriberIPTable
-from magma.monitord.icmp_monitoring import ICMPMonitoring
from magma.monitord.cpe_monitoring import CpeMonitoringModule
+from magma.monitord.icmp_monitoring import ICMPMonitoring
LOCALHOST = '127.0.0.1'
diff --git a/lte/gateway/python/magma/pipelined/app/access_control.py b/lte/gateway/python/magma/pipelined/app/access_control.py
index 745a2f61ab32..ad49e74af0e9 100644
--- a/lte/gateway/python/magma/pipelined/app/access_control.py
+++ b/lte/gateway/python/magma/pipelined/app/access_control.py
@@ -14,12 +14,11 @@
import ipaddress
from collections import namedtuple
-from ryu.lib.packet import ether_types
-
+from magma.pipelined.app.base import ControllerType, MagmaController
from magma.pipelined.openflow import flows
from magma.pipelined.openflow.magma_match import MagmaMatch
from magma.pipelined.openflow.registers import Direction
-from magma.pipelined.app.base import MagmaController, ControllerType
+from ryu.lib.packet import ether_types
class AccessControlController(MagmaController):
diff --git a/lte/gateway/python/magma/pipelined/app/arp.py b/lte/gateway/python/magma/pipelined/app/arp.py
index ce510ace8a1c..21e7dd1c6f48 100644
--- a/lte/gateway/python/magma/pipelined/app/arp.py
+++ b/lte/gateway/python/magma/pipelined/app/arp.py
@@ -11,23 +11,20 @@
limitations under the License.
"""
-import netifaces
import ipaddress
-
from collections import namedtuple
+import netifaces
from lte.protos.pipelined_pb2 import SetupFlowsResult, SetupUEMacRequest
-
from magma.common.misc_utils import cidr_to_ip_netmask_tuple
-from magma.pipelined.app.base import MagmaController, ControllerType
+from magma.pipelined.app.base import ControllerType, MagmaController
+from magma.pipelined.directoryd_client import get_all_records
+from magma.pipelined.mobilityd_client import mobilityd_list_ip_blocks
from magma.pipelined.openflow import flows
from magma.pipelined.openflow.magma_match import MagmaMatch
from magma.pipelined.openflow.registers import Direction, load_passthrough
-from magma.pipelined.directoryd_client import get_all_records
-from magma.pipelined.mobilityd_client import mobilityd_list_ip_blocks
-
from ryu.controller import dpset
-from ryu.lib.packet import ether_types, arp
+from ryu.lib.packet import arp, ether_types
# This is used to determine valid ip-blocks.
MAX_SUBNET_PREFIX_LEN = 31
diff --git a/lte/gateway/python/magma/pipelined/app/base.py b/lte/gateway/python/magma/pipelined/app/base.py
index 07e6e512bd1e..92620723e5f3 100644
--- a/lte/gateway/python/magma/pipelined/app/base.py
+++ b/lte/gateway/python/magma/pipelined/app/base.py
@@ -10,24 +10,23 @@
See the License for the specific language governing permissions and
limitations under the License.
"""
-from enum import Enum
import time
-
-from ryu import utils
-from ryu.base import app_manager
-from ryu.controller import dpset
-from ryu.controller import ofp_event
-from ryu.controller.handler import CONFIG_DISPATCHER
-from ryu.controller.handler import MAIN_DISPATCHER
-from ryu.controller.handler import HANDSHAKE_DISPATCHER
-from ryu.controller.handler import set_ev_cls
-from ryu.ofproto import ofproto_v1_4
+from enum import Enum
from lte.protos.pipelined_pb2 import SetupFlowsResult
from magma.pipelined.bridge_util import BridgeTools, DatapathLookupError
from magma.pipelined.metrics import OPENFLOW_ERROR_MSG
from magma.pipelined.openflow.exceptions import MagmaOFError
-
+from ryu import utils
+from ryu.base import app_manager
+from ryu.controller import dpset, ofp_event
+from ryu.controller.handler import (
+ CONFIG_DISPATCHER,
+ HANDSHAKE_DISPATCHER,
+ MAIN_DISPATCHER,
+ set_ev_cls,
+)
+from ryu.ofproto import ofproto_v1_4
global_epoch = int(time.time())
diff --git a/lte/gateway/python/magma/pipelined/app/check_quota.py b/lte/gateway/python/magma/pipelined/app/check_quota.py
index b407373c92ae..43be21b22628 100644
--- a/lte/gateway/python/magma/pipelined/app/check_quota.py
+++ b/lte/gateway/python/magma/pipelined/app/check_quota.py
@@ -10,24 +10,26 @@
See the License for the specific language governing permissions and
limitations under the License.
"""
-import netifaces
import ipaddress
-from typing import NamedTuple, Dict, List
-
-from ryu.lib.packet import ether_types
-from ryu.ofproto.inet import IPPROTO_TCP
-from ryu.controller.controller import Datapath
-from ryu.ofproto.ofproto_v1_4 import OFPP_LOCAL
+from typing import Dict, List, NamedTuple
-from lte.protos.pipelined_pb2 import SubscriberQuotaUpdate, SetupFlowsResult
-from magma.pipelined.app.base import MagmaController, ControllerType
-from magma.pipelined.app.inout import INGRESS, EGRESS
+import netifaces
+from lte.protos.pipelined_pb2 import SetupFlowsResult, SubscriberQuotaUpdate
+from magma.pipelined.app.base import ControllerType, MagmaController
+from magma.pipelined.app.inout import EGRESS, INGRESS
from magma.pipelined.app.ue_mac import UEMacAddressController
from magma.pipelined.imsi import encode_imsi
from magma.pipelined.openflow import flows
from magma.pipelined.openflow.magma_match import MagmaMatch
-from magma.pipelined.openflow.registers import Direction, IMSI_REG, \
- DIRECTION_REG
+from magma.pipelined.openflow.registers import (
+ DIRECTION_REG,
+ IMSI_REG,
+ Direction,
+)
+from ryu.controller.controller import Datapath
+from ryu.lib.packet import ether_types
+from ryu.ofproto.inet import IPPROTO_TCP
+from ryu.ofproto.ofproto_v1_4 import OFPP_LOCAL
class CheckQuotaController(MagmaController):
diff --git a/lte/gateway/python/magma/pipelined/app/classifier.py b/lte/gateway/python/magma/pipelined/app/classifier.py
index c0ef438d6be3..ab2b04d566bf 100644
--- a/lte/gateway/python/magma/pipelined/app/classifier.py
+++ b/lte/gateway/python/magma/pipelined/app/classifier.py
@@ -10,23 +10,21 @@
See the License for the specific language governing permissions and
limitations under the License.
"""
-import subprocess
import ipaddress
import socket
+import subprocess
from collections import namedtuple
-from ryu.ofproto.ofproto_v1_4 import OFPP_LOCAL
-from .base import MagmaController
+from lte.protos.mobilityd_pb2 import IPAddress
+from magma.pipelined.app.base import ControllerType, MagmaController
+from magma.pipelined.app.inout import INGRESS
from magma.pipelined.openflow import flows
from magma.pipelined.openflow.magma_match import MagmaMatch
-from magma.pipelined.app.inout import INGRESS
-from ryu.lib.packet import ether_types
-from magma.pipelined.app.base import MagmaController, ControllerType
+from magma.pipelined.openflow.registers import TUN_PORT_REG, Direction
+from magma.pipelined.policy_converters import get_eth_type, get_ue_ip_match_args
from magma.pipelined.utils import Utils
-from magma.pipelined.openflow.registers import TUN_PORT_REG
-from lte.protos.mobilityd_pb2 import IPAddress
-from magma.pipelined.policy_converters import get_ue_ip_match_args, get_eth_type
-from magma.pipelined.openflow.registers import Direction
+from ryu.lib.packet import ether_types
+from ryu.ofproto.ofproto_v1_4 import OFPP_LOCAL
GTP_PORT_MAC = "02:00:00:00:00:01"
TUNNEL_OAM_FLAG = 1
diff --git a/lte/gateway/python/magma/pipelined/app/conntrack.py b/lte/gateway/python/magma/pipelined/app/conntrack.py
index e29f5c295c79..276990ee2436 100644
--- a/lte/gateway/python/magma/pipelined/app/conntrack.py
+++ b/lte/gateway/python/magma/pipelined/app/conntrack.py
@@ -10,13 +10,11 @@
See the License for the specific language governing permissions and
limitations under the License.
"""
-from ryu.lib.packet import ether_types
-from ryu.ofproto.nicira_ext import ofs_nbits
-
-
-from .base import MagmaController, ControllerType
+from magma.pipelined.app.base import ControllerType, MagmaController
from magma.pipelined.openflow import flows
from magma.pipelined.openflow.magma_match import MagmaMatch
+from ryu.lib.packet import ether_types
+from ryu.ofproto.nicira_ext import ofs_nbits
class ConntrackController(MagmaController):
diff --git a/lte/gateway/python/magma/pipelined/app/dpi.py b/lte/gateway/python/magma/pipelined/app/dpi.py
index a571f6bc92f1..716b61a48a82 100644
--- a/lte/gateway/python/magma/pipelined/app/dpi.py
+++ b/lte/gateway/python/magma/pipelined/app/dpi.py
@@ -10,19 +10,22 @@
See the License for the specific language governing permissions and
limitations under the License.
"""
+import logging
import shlex
import subprocess
-import logging
-from magma.pipelined.openflow import flows
-from magma.pipelined.bridge_util import BridgeTools
-from magma.pipelined.app.base import MagmaController, ControllerType
+from lte.protos.pipelined_pb2 import FlowRequest
+from magma.pipelined.app.base import ControllerType, MagmaController
from magma.pipelined.app.ipfix import IPFIXController
+from magma.pipelined.bridge_util import BridgeTools
+from magma.pipelined.openflow import flows
from magma.pipelined.openflow.magma_match import MagmaMatch
from magma.pipelined.openflow.registers import DPI_REG
-from magma.pipelined.policy_converters import FlowMatchError, \
- flow_match_to_magma_match, flip_flow_match
-from lte.protos.pipelined_pb2 import FlowRequest
+from magma.pipelined.policy_converters import (
+ FlowMatchError,
+ flip_flow_match,
+ flow_match_to_magma_match,
+)
# TODO might move to config file
# Current classification will finalize if found in APP_PROTOS, if found in
diff --git a/lte/gateway/python/magma/pipelined/app/enforcement.py b/lte/gateway/python/magma/pipelined/app/enforcement.py
index fe001a61e94e..26ad42a65b55 100644
--- a/lte/gateway/python/magma/pipelined/app/enforcement.py
+++ b/lte/gateway/python/magma/pipelined/app/enforcement.py
@@ -11,27 +11,27 @@
limitations under the License.
"""
from lte.protos.pipelined_pb2 import RuleModResult
-
-from magma.pipelined.app.base import MagmaController, ControllerType
+from magma.pipelined.app.base import ControllerType, MagmaController
from magma.pipelined.app.enforcement_stats import EnforcementStatsController
from magma.pipelined.app.policy_mixin import PolicyMixin
-from magma.pipelined.app.restart_mixin import RestartMixin, DefaultMsgsMap
-
+from magma.pipelined.app.restart_mixin import DefaultMsgsMap, RestartMixin
from magma.pipelined.imsi import encode_imsi
from magma.pipelined.openflow import flows
+from magma.pipelined.openflow.exceptions import MagmaDPDisconnectedError
from magma.pipelined.openflow.magma_match import MagmaMatch
from magma.pipelined.openflow.messages import MessageHub
from magma.pipelined.openflow.registers import Direction
-from magma.pipelined.policy_converters import FlowMatchError, \
- get_ue_ip_match_args, get_eth_type
-from magma.pipelined.redirect import RedirectionManager, RedirectException
+from magma.pipelined.policy_converters import (
+ FlowMatchError,
+ get_eth_type,
+ get_ue_ip_match_args,
+)
from magma.pipelined.qos.common import QosManager
from magma.pipelined.qos.qos_meter_impl import MeterManager
-
+from magma.pipelined.redirect import RedirectException, RedirectionManager
+from magma.pipelined.utils import Utils
from ryu.controller import ofp_event
from ryu.controller.handler import MAIN_DISPATCHER, set_ev_cls
-from magma.pipelined.utils import Utils
-from magma.pipelined.openflow.exceptions import MagmaDPDisconnectedError
class EnforcementController(PolicyMixin, RestartMixin, MagmaController):
@@ -151,7 +151,7 @@ def _get_default_flow_msgs(self, datapath) -> DefaultMsgsMap:
return {self.tbl_num: [msg]}
- def _get_rule_match_flow_msgs(self, imsi, msisdn: bytes, uplink_tunnel: int, ip_addr, apn_ambr, rule):
+ def _get_rule_match_flow_msgs(self, imsi, msisdn: bytes, uplink_tunnel: int, ip_addr, apn_ambr, rule, version):
"""
Get flow msgs to get stats for a particular rule. Flows will match on
IMSI, cookie (the rule num), in/out direction
@@ -169,8 +169,6 @@ def _get_rule_match_flow_msgs(self, imsi, msisdn: bytes, uplink_tunnel: int, ip_
flow_adds = []
for flow in rule.flow_list:
try:
- version = self._session_rule_version_mapper.get_version(imsi, ip_addr,
- rule.id)
flow_adds.extend(self._get_classify_rule_flow_msgs(
imsi, msisdn, uplink_tunnel, ip_addr, apn_ambr, flow, rule_num, priority,
rule.qos, rule.hard_timeout, rule.id, rule.app_name,
@@ -184,7 +182,7 @@ def _get_rule_match_flow_msgs(self, imsi, msisdn: bytes, uplink_tunnel: int, ip_
raise err
return flow_adds
- def _install_flow_for_rule(self, imsi, msisdn: bytes, uplink_tunnel: int, ip_addr, apn_ambr, rule):
+ def _install_flow_for_rule(self, imsi, msisdn: bytes, uplink_tunnel: int, ip_addr, apn_ambr, rule, version):
"""
Install a flow to get stats for a particular rule. Flows will match on
IMSI, cookie (the rule num), in/out direction
@@ -197,7 +195,7 @@ def _install_flow_for_rule(self, imsi, msisdn: bytes, uplink_tunnel: int, ip_add
rule (PolicyRule): policy rule proto
"""
if rule.redirect.support == rule.redirect.ENABLED:
- return self._install_redirect_flow(imsi, ip_addr, rule)
+ return self._install_redirect_flow(imsi, ip_addr, rule, version)
if not rule.flow_list:
self.logger.error('The flow list for imsi %s, rule.id - %s'
@@ -206,7 +204,7 @@ def _install_flow_for_rule(self, imsi, msisdn: bytes, uplink_tunnel: int, ip_add
flow_adds = []
try:
- flow_adds = self._get_rule_match_flow_msgs(imsi, msisdn, uplink_tunnel, ip_addr, apn_ambr, rule)
+ flow_adds = self._get_rule_match_flow_msgs(imsi, msisdn, uplink_tunnel, ip_addr, apn_ambr, rule, version)
except FlowMatchError:
return RuleModResult.FAILURE
@@ -218,18 +216,15 @@ def _install_flow_for_rule(self, imsi, msisdn: bytes, uplink_tunnel: int, ip_add
return RuleModResult.FAILURE
return self._wait_for_rule_responses(imsi, ip_addr, rule, chan)
- def _install_redirect_flow(self, imsi, ip_addr, rule):
+ def _install_redirect_flow(self, imsi, ip_addr, rule, version):
rule_num = self._rule_mapper.get_or_create_rule_num(rule.id)
- rule_version = self._session_rule_version_mapper.get_version(imsi,
- ip_addr,
- rule.id)
priority = Utils.get_of_priority(rule.priority)
redirect_request = RedirectionManager.RedirectRequest(
imsi=imsi,
ip_addr=ip_addr.address.decode('utf-8'),
rule=rule,
rule_num=rule_num,
- rule_version=rule_version,
+ rule_version=version,
priority=priority)
try:
self._redirect_manager.setup_lte_redirect(
diff --git a/lte/gateway/python/magma/pipelined/app/enforcement_stats.py b/lte/gateway/python/magma/pipelined/app/enforcement_stats.py
index 5f8d505318b8..50cf21e73714 100644
--- a/lte/gateway/python/magma/pipelined/app/enforcement_stats.py
+++ b/lte/gateway/python/magma/pipelined/app/enforcement_stats.py
@@ -13,34 +13,44 @@
import os
from collections import defaultdict
-from lte.protos.pipelined_pb2 import RuleModResult
from lte.protos.mobilityd_pb2 import IPAddress
+from lte.protos.pipelined_pb2 import RuleModResult
from lte.protos.policydb_pb2 import FlowDescription
-from lte.protos.session_manager_pb2 import RuleRecord, \
- RuleRecordTable
+from lte.protos.session_manager_pb2 import RuleRecord, RuleRecordTable
+from magma.pipelined.app.base import (
+ ControllerType,
+ MagmaController,
+ global_epoch,
+)
+from magma.pipelined.app.policy_mixin import (
+ DROP_FLOW_STATS,
+ IGNORE_STATS,
+ PROCESS_STATS,
+ PolicyMixin,
+)
+from magma.pipelined.app.restart_mixin import DefaultMsgsMap, RestartMixin
+from magma.pipelined.imsi import decode_imsi, encode_imsi
+from magma.pipelined.openflow import flows, messages
+from magma.pipelined.openflow.exceptions import (
+ MagmaDPDisconnectedError,
+ MagmaOFError,
+)
+from magma.pipelined.openflow.magma_match import MagmaMatch
+from magma.pipelined.openflow.messages import MessageHub, MsgChannel
+from magma.pipelined.openflow.registers import (
+ DIRECTION_REG,
+ IMSI_REG,
+ RULE_VERSION_REG,
+ SCRATCH_REGS,
+ Direction,
+)
+from magma.pipelined.policy_converters import get_eth_type, get_ue_ip_match_args
+from magma.pipelined.utils import Utils
from ryu.controller import dpset, ofp_event
from ryu.controller.handler import MAIN_DISPATCHER, set_ev_cls
from ryu.lib import hub
from ryu.ofproto.ofproto_v1_4 import OFPMPF_REPLY_MORE
-from magma.pipelined.app.base import MagmaController, ControllerType, \
- global_epoch
-from magma.pipelined.app.policy_mixin import PolicyMixin, IGNORE_STATS, \
- PROCESS_STATS, DROP_FLOW_STATS
-from magma.pipelined.app.restart_mixin import RestartMixin, DefaultMsgsMap
-from magma.pipelined.policy_converters import get_ue_ip_match_args, \
- get_eth_type
-from magma.pipelined.openflow import messages, flows
-from magma.pipelined.openflow.exceptions import MagmaOFError
-from magma.pipelined.imsi import decode_imsi, encode_imsi
-from magma.pipelined.openflow.magma_match import MagmaMatch
-from magma.pipelined.openflow.messages import MsgChannel, MessageHub
-from magma.pipelined.utils import Utils
-from magma.pipelined.openflow.registers import Direction, DIRECTION_REG, \
- IMSI_REG, RULE_VERSION_REG, SCRATCH_REGS
-from magma.pipelined.openflow.exceptions import MagmaDPDisconnectedError
-
-
ETH_FRAME_SIZE_BYTES = 14
@@ -143,7 +153,7 @@ def cleanup_on_disconnect(self, datapath):
if self._clean_restart:
self.delete_all_flows(datapath)
- def _install_flow_for_rule(self, imsi, msisdn: bytes, uplink_tunnel: int, ip_addr, apn_ambr, rule):
+ def _install_flow_for_rule(self, imsi, msisdn: bytes, uplink_tunnel: int, ip_addr, apn_ambr, rule, version):
"""
Install a flow to get stats for a particular rule. Flows will match on
IMSI, cookie (the rule num), in/out direction
@@ -161,7 +171,7 @@ def fail(err):
rule.id, imsi, err)
return RuleModResult.FAILURE
- msgs = self._get_rule_match_flow_msgs(imsi, msisdn, uplink_tunnel, ip_addr, apn_ambr, rule)
+ msgs = self._get_rule_match_flow_msgs(imsi, msisdn, uplink_tunnel, ip_addr, apn_ambr, rule, version)
try:
chan = self._msg_hub.send(msgs, self._datapath)
@@ -188,13 +198,11 @@ def _handle_error(self, ev):
self._msg_hub.handle_error(ev)
# pylint: disable=protected-access,unused-argument
- def _get_rule_match_flow_msgs(self, imsi, _, __, ip_addr, ambr, rule):
+ def _get_rule_match_flow_msgs(self, imsi, _, __, ip_addr, ambr, rule, version):
"""
Returns flow add messages used for rule matching.
"""
rule_num = self._rule_mapper.get_or_create_rule_num(rule.id)
- version = self._session_rule_version_mapper.get_version(imsi, ip_addr,
- rule.id)
self.logger.debug(
'Installing flow for %s with rule num %s (version %s)', imsi,
rule_num, version)
@@ -270,7 +278,7 @@ def _get_default_flow_msgs_for_subscriber(self, imsi, ip_addr):
flows.get_add_drop_flow_msg(self._datapath, self.tbl_num, match_out,
priority=Utils.DROP_PRIORITY)]
- def _install_redirect_flow(self, imsi, ip_addr, rule):
+ def _install_redirect_flow(self, imsi, ip_addr, rule, version):
pass
def _install_default_flow_for_subscriber(self, imsi, ip_addr):
diff --git a/lte/gateway/python/magma/pipelined/app/gy.py b/lte/gateway/python/magma/pipelined/app/gy.py
index f424486c3ee2..d19d84157530 100644
--- a/lte/gateway/python/magma/pipelined/app/gy.py
+++ b/lte/gateway/python/magma/pipelined/app/gy.py
@@ -11,25 +11,22 @@
limitations under the License.
"""
from lte.protos.pipelined_pb2 import RuleModResult
-
-from magma.pipelined.app.base import MagmaController, ControllerType
+from magma.pipelined.app.base import ControllerType, MagmaController
from magma.pipelined.app.enforcement_stats import EnforcementStatsController
+from magma.pipelined.app.inout import EGRESS
from magma.pipelined.app.policy_mixin import PolicyMixin
-from magma.pipelined.app.restart_mixin import RestartMixin, DefaultMsgsMap
-
+from magma.pipelined.app.restart_mixin import DefaultMsgsMap, RestartMixin
from magma.pipelined.imsi import encode_imsi
from magma.pipelined.openflow import flows
from magma.pipelined.openflow.magma_match import MagmaMatch
from magma.pipelined.openflow.messages import MessageHub
from magma.pipelined.policy_converters import FlowMatchError
-from magma.pipelined.redirect import RedirectionManager, RedirectException
-from magma.pipelined.app.inout import EGRESS
from magma.pipelined.qos.common import QosManager
from magma.pipelined.qos.qos_meter_impl import MeterManager
-
+from magma.pipelined.redirect import RedirectException, RedirectionManager
+from magma.pipelined.utils import Utils
from ryu.controller import ofp_event
from ryu.controller.handler import MAIN_DISPATCHER, set_ev_cls
-from magma.pipelined.utils import Utils
class GYController(PolicyMixin, RestartMixin, MagmaController):
@@ -160,7 +157,7 @@ def _deactivate_flow_for_rule(self, imsi, ip_addr, rule_id):
self._qos_mgr.remove_subscriber_qos(imsi, num)
self._remove_he_flows(ip_addr, rule_id)
- def _install_flow_for_rule(self, imsi, msisdn:bytes, uplink_tunnel: int, ip_addr, apn_ambr, rule):
+ def _install_flow_for_rule(self, imsi, msisdn:bytes, uplink_tunnel: int, ip_addr, apn_ambr, rule, version):
"""
Install a flow to get stats for a particular rule. Flows will match on
IMSI, cookie (the rule num), in/out direction
@@ -172,7 +169,7 @@ def _install_flow_for_rule(self, imsi, msisdn:bytes, uplink_tunnel: int, ip_addr
rule (PolicyRule): policy rule proto
"""
if rule.redirect.support == rule.redirect.ENABLED:
- self._install_redirect_flow(imsi, ip_addr, rule)
+ self._install_redirect_flow(imsi, ip_addr, rule, version)
return RuleModResult.SUCCESS
if not rule.flow_list:
@@ -182,7 +179,7 @@ def _install_flow_for_rule(self, imsi, msisdn:bytes, uplink_tunnel: int, ip_addr
flow_adds = []
try:
- flow_adds = self._get_rule_match_flow_msgs(imsi, msisdn, uplink_tunnel, ip_addr, apn_ambr, rule)
+ flow_adds = self._get_rule_match_flow_msgs(imsi, msisdn, uplink_tunnel, ip_addr, apn_ambr, rule, version)
except FlowMatchError:
return RuleModResult.FAILURE
@@ -215,11 +212,8 @@ def _install_default_flows(self, datapath):
priority=flows.MINIMUM_PRIORITY,
resubmit_table=self.next_main_table)
- def _install_redirect_flow(self, imsi, ip_addr, rule):
+ def _install_redirect_flow(self, imsi, ip_addr, rule, version):
rule_num = self._rule_mapper.get_or_create_rule_num(rule.id)
- rule_version = self._session_rule_version_mapper.get_version(imsi,
- ip_addr,
- rule.id)
# CWF generates an internal IP for redirection so ip_addr is not needed
if self._setup_type == 'CWF':
ip_addr_str = None
@@ -233,7 +227,7 @@ def _install_redirect_flow(self, imsi, ip_addr, rule):
ip_addr=ip_addr_str,
rule=rule,
rule_num=rule_num,
- rule_version=rule_version,
+ rule_version=version,
priority=priority)
try:
if self._setup_type == 'CWF':
@@ -267,7 +261,7 @@ def _get_default_flow_msgs(self, datapath) -> DefaultMsgsMap:
return {self.tbl_num: [msg]}
- def _get_rule_match_flow_msgs(self, imsi, msisdn: bytes, uplink_tunnel: int, ip_addr, apn_ambr, rule):
+ def _get_rule_match_flow_msgs(self, imsi, msisdn: bytes, uplink_tunnel: int, ip_addr, apn_ambr, rule, version):
"""
Get flow msgs to get stats for a particular rule. Flows will match on
IMSI, cookie (the rule num), in/out direction
@@ -285,8 +279,6 @@ def _get_rule_match_flow_msgs(self, imsi, msisdn: bytes, uplink_tunnel: int, ip_
flow_adds = []
for flow in rule.flow_list:
try:
- version = self._session_rule_version_mapper.get_version(imsi, ip_addr,
- rule.id)
flow_adds.extend(self._get_classify_rule_flow_msgs(
imsi, msisdn, uplink_tunnel, ip_addr, apn_ambr, flow, rule_num, priority,
rule.qos, rule.hard_timeout, rule.id, rule.app_name,
diff --git a/lte/gateway/python/magma/pipelined/app/he.py b/lte/gateway/python/magma/pipelined/app/he.py
index 32d9dfb641cc..d8d0d95002f0 100644
--- a/lte/gateway/python/magma/pipelined/app/he.py
+++ b/lte/gateway/python/magma/pipelined/app/he.py
@@ -10,29 +10,39 @@
See the License for the specific language governing permissions and
limitations under the License.
"""
+import logging
from collections import namedtuple
from threading import Lock
from typing import List
-from ryu.lib.packet import ether_types
-from ryu.lib.packet.in_proto import IPPROTO_TCP
-
-from .base import MagmaController, ControllerType
-from magma.pipelined.openflow import flows
-from magma.pipelined.openflow.magma_match import MagmaMatch
-from magma.pipelined.openflow.registers import load_direction, Direction, \
- load_passthrough, set_proxy_tag, set_in_port, load_imsi, \
- PROXY_TAG_TO_PROXY, set_tun_id
-from magma.pipelined.envoy_client import activate_he_urls_for_ue, \
- deactivate_he_urls_for_ue
-from magma.pipelined.encoding import encrypt_str, get_hash, encode_str
-
from lte.protos.mobilityd_pb2 import IPAddress
+from magma.pipelined.app.base import ControllerType, MagmaController
from magma.pipelined.bridge_util import BridgeTools, DatapathLookupError
-from magma.pipelined.policy_converters import get_ue_ip_match_args, \
- get_eth_type, convert_ipv4_str_to_ip_proto, ipv4_address_to_str
-
-import logging
+from magma.pipelined.encoding import encode_str, encrypt_str, get_hash
+from magma.pipelined.envoy_client import (
+ activate_he_urls_for_ue,
+ deactivate_he_urls_for_ue,
+)
+from magma.pipelined.openflow import flows
+from magma.pipelined.openflow.magma_match import MagmaMatch
+from magma.pipelined.openflow.registers import (
+ PROXY_TAG_TO_PROXY,
+ Direction,
+ load_direction,
+ load_imsi,
+ load_passthrough,
+ set_in_port,
+ set_proxy_tag,
+ set_tun_id,
+)
+from magma.pipelined.policy_converters import (
+ convert_ipv4_str_to_ip_proto,
+ get_eth_type,
+ get_ue_ip_match_args,
+ ipv4_address_to_str,
+)
+from ryu.lib.packet import ether_types
+from ryu.lib.packet.in_proto import IPPROTO_TCP
PROXY_PORT_NAME = 'proxy_port'
HTTP_PORT = 80
diff --git a/lte/gateway/python/magma/pipelined/app/inout.py b/lte/gateway/python/magma/pipelined/app/inout.py
index 237f9aa84b54..4b582628c5a1 100644
--- a/lte/gateway/python/magma/pipelined/app/inout.py
+++ b/lte/gateway/python/magma/pipelined/app/inout.py
@@ -12,35 +12,38 @@
"""
import ipaddress
import threading
-
from collections import namedtuple
-from ryu.ofproto.ofproto_v1_4 import OFPP_LOCAL
-
-from scapy.arch import get_if_hwaddr, get_if_addr
-from scapy.data import ETHER_BROADCAST, ETH_P_ALL
-from scapy.error import Scapy_Exception
-from scapy.layers.l2 import ARP, Ether, Dot1Q
-from scapy.sendrecv import srp1
-
-from .base import MagmaController
-from magma.pipelined.mobilityd_client import get_mobilityd_gw_info, \
- set_mobilityd_gw_info
from lte.protos.mobilityd_pb2 import IPAddress
-
+from magma.pipelined.app.base import MagmaController
from magma.pipelined.app.li_mirror import LIMirrorController
-from magma.pipelined.openflow import flows
+from magma.pipelined.app.restart_mixin import DefaultMsgsMap, RestartMixin
from magma.pipelined.bridge_util import BridgeTools, DatapathLookupError
+from magma.pipelined.mobilityd_client import (
+ get_mobilityd_gw_info,
+ set_mobilityd_gw_info,
+)
+from magma.pipelined.openflow import flows
from magma.pipelined.openflow.magma_match import MagmaMatch
from magma.pipelined.openflow.messages import MessageHub, MsgChannel
-from magma.pipelined.openflow.registers import load_direction, Direction, \
- PASSTHROUGH_REG_VAL, TUN_PORT_REG, PROXY_TAG_TO_PROXY, REG_ZERO_VAL
-from magma.pipelined.app.restart_mixin import RestartMixin, DefaultMsgsMap
-
-from ryu.lib import hub
-from ryu.lib.packet import ether_types
+from magma.pipelined.openflow.registers import (
+ PASSTHROUGH_REG_VAL,
+ PROXY_TAG_TO_PROXY,
+ REG_ZERO_VAL,
+ TUN_PORT_REG,
+ Direction,
+ load_direction,
+)
from ryu.controller import ofp_event
from ryu.controller.handler import MAIN_DISPATCHER, set_ev_cls
+from ryu.lib import hub
+from ryu.lib.packet import ether_types
+from ryu.ofproto.ofproto_v1_4 import OFPP_LOCAL
+from scapy.arch import get_if_addr, get_if_hwaddr
+from scapy.data import ETH_P_ALL, ETHER_BROADCAST
+from scapy.error import Scapy_Exception
+from scapy.layers.l2 import ARP, Dot1Q, Ether
+from scapy.sendrecv import srp1
# ingress and egress service names -- used by other controllers
diff --git a/lte/gateway/python/magma/pipelined/app/ipfix.py b/lte/gateway/python/magma/pipelined/app/ipfix.py
index 6d783ced0102..51ef465ee877 100644
--- a/lte/gateway/python/magma/pipelined/app/ipfix.py
+++ b/lte/gateway/python/magma/pipelined/app/ipfix.py
@@ -12,13 +12,14 @@
"""
import shlex
import subprocess
-from typing import NamedTuple, Dict
+from typing import Dict, NamedTuple
-from magma.pipelined.app.base import MagmaController, ControllerType
+from magma.pipelined.app.base import ControllerType, MagmaController
+from magma.pipelined.imsi import encode_imsi
from magma.pipelined.openflow import flows
-from ryu.controller.controller import Datapath
from magma.pipelined.openflow.magma_match import MagmaMatch
-from magma.pipelined.imsi import encode_imsi
+from ryu.controller.controller import Datapath
+
class IPFIXController(MagmaController):
"""
diff --git a/lte/gateway/python/magma/pipelined/app/ipv6_solicitation.py b/lte/gateway/python/magma/pipelined/app/ipv6_solicitation.py
index c46d007c651e..cb2effbf0e70 100644
--- a/lte/gateway/python/magma/pipelined/app/ipv6_solicitation.py
+++ b/lte/gateway/python/magma/pipelined/app/ipv6_solicitation.py
@@ -12,18 +12,15 @@
"""
from collections import namedtuple
-from ryu.controller import ofp_event
-from ryu.controller.handler import MAIN_DISPATCHER, set_ev_cls
-from magma.pipelined.app.base import MagmaController, ControllerType
+from magma.pipelined.app.base import ControllerType, MagmaController
+from magma.pipelined.ipv6_prefix_store import get_ipv6_interface_id
from magma.pipelined.openflow import flows
from magma.pipelined.openflow.magma_match import MagmaMatch
-from magma.pipelined.ipv6_prefix_store import get_ipv6_interface_id
-from magma.pipelined.openflow.registers import Direction, DIRECTION_REG
-
-from ryu.controller import dpset
+from magma.pipelined.openflow.registers import DIRECTION_REG, Direction
+from ryu.controller import dpset, ofp_event
+from ryu.controller.handler import MAIN_DISPATCHER, set_ev_cls
+from ryu.lib.packet import ether_types, ethernet, icmpv6, in_proto, ipv6, packet
from ryu.ofproto.inet import IPPROTO_ICMPV6
-from ryu.lib.packet import packet, ethernet, ether_types, icmpv6, ipv6, \
- in_proto
class IPV6SolicitationController(MagmaController):
diff --git a/lte/gateway/python/magma/pipelined/app/li_mirror.py b/lte/gateway/python/magma/pipelined/app/li_mirror.py
index e6fbe2f542bc..e06ef2018c73 100644
--- a/lte/gateway/python/magma/pipelined/app/li_mirror.py
+++ b/lte/gateway/python/magma/pipelined/app/li_mirror.py
@@ -10,16 +10,14 @@
See the License for the specific language governing permissions and
limitations under the License.
"""
-from magma.pipelined.openflow import flows
-from magma.pipelined.bridge_util import BridgeTools
-from magma.pipelined.app.base import MagmaController, ControllerType
+from lte.protos.mconfig import mconfigs_pb2
from magma.configuration.mconfig_managers import load_service_mconfig
-
+from magma.pipelined.app.base import ControllerType, MagmaController
+from magma.pipelined.bridge_util import BridgeTools
from magma.pipelined.imsi import encode_imsi
+from magma.pipelined.openflow import flows
from magma.pipelined.openflow.magma_match import MagmaMatch
from magma.pipelined.openflow.registers import Direction
-from lte.protos.mconfig import mconfigs_pb2
-
from ryu.lib import hub
from ryu.lib.packet import ether_types
diff --git a/lte/gateway/python/magma/pipelined/app/ng_services.py b/lte/gateway/python/magma/pipelined/app/ng_services.py
index 5b4f30871a2c..ba876ab43d05 100644
--- a/lte/gateway/python/magma/pipelined/app/ng_services.py
+++ b/lte/gateway/python/magma/pipelined/app/ng_services.py
@@ -10,10 +10,11 @@
See the License for the specific language governing permissions and
limitations under the License.
"""
-from .base import MagmaController, ControllerType
+from magma.pipelined.app.base import ControllerType, MagmaController
from magma.pipelined.ng_manager.node_state_manager import NodeStateManager
from magma.pipelined.ng_manager.session_state_manager import SessionStateManager
+
class NGServiceController(MagmaController):
"""
This class is intended to be a place holder for
diff --git a/lte/gateway/python/magma/pipelined/app/policy_mixin.py b/lte/gateway/python/magma/pipelined/app/policy_mixin.py
index 16734b89da85..c1ac04d0fa75 100644
--- a/lte/gateway/python/magma/pipelined/app/policy_mixin.py
+++ b/lte/gateway/python/magma/pipelined/app/policy_mixin.py
@@ -10,24 +10,34 @@
See the License for the specific language governing permissions and
limitations under the License.
"""
-from typing import List
from abc import ABCMeta, abstractmethod
+from typing import List
-from lte.protos.pipelined_pb2 import RuleModResult, ActivateFlowsResult, \
- ActivateFlowsRequest
-from magma.pipelined.openflow import flows
-from magma.pipelined.openflow.registers import SCRATCH_REGS, RULE_VERSION_REG, \
- RULE_NUM_REG
-from magma.pipelined.openflow.messages import MsgChannel
-
+from lte.protos.mobilityd_pb2 import IPAddress
+from lte.protos.pipelined_pb2 import (
+ ActivateFlowsRequest,
+ ActivateFlowsResult,
+ RuleModResult,
+)
from lte.protos.policydb_pb2 import PolicyRule
from magma.pipelined.app.dpi import UNCLASSIFIED_PROTO_ID, get_app_id
from magma.pipelined.imsi import encode_imsi
-from magma.pipelined.policy_converters import get_direction_for_match, \
- flow_match_to_magma_match, get_flow_ip_dst, ipv4_address_to_str, \
- FlowMatchError, convert_ipv4_str_to_ip_proto
-from lte.protos.mobilityd_pb2 import IPAddress
-
+from magma.pipelined.openflow import flows
+from magma.pipelined.openflow.messages import MsgChannel
+from magma.pipelined.openflow.registers import (
+ RULE_NUM_REG,
+ RULE_VERSION_REG,
+ SCRATCH_REGS,
+)
+from magma.pipelined.policy_converters import (
+ FlowMatchError,
+ convert_ipv4_str_to_ip_proto,
+ convert_ipv6_bytes_to_ip_proto,
+ flow_match_to_magma_match,
+ get_direction_for_match,
+ get_flow_ip_dst,
+ ipv4_address_to_str,
+)
from magma.pipelined.qos.types import QosInfo
from magma.pipelined.utils import Utils
@@ -47,6 +57,7 @@ def __init__(self, *args, **kwargs):
super(PolicyMixin, self).__init__(*args, **kwargs)
self._datapath = None
self._rule_mapper = kwargs['rule_id_mapper']
+ self._setup_type = kwargs['config']['setup_type']
self._session_rule_version_mapper = kwargs[
'session_rule_version_mapper']
if 'proxy' in kwargs['app_futures']:
@@ -55,7 +66,7 @@ def __init__(self, *args, **kwargs):
self.proxy_controller_fut = None
self.proxy_controller = None
- def activate_rules(self, imsi, msisdn: bytes, uplink_tunnel: int, ip_addr, apn_ambr, dynamic_rules):
+ def activate_rules(self, imsi, msisdn: bytes, uplink_tunnel: int, ip_addr, apn_ambr, policies):
"""
Activate the flows for a subscriber based on the rules stored in Redis.
During activation, a default flow may be installed for the subscriber.
@@ -65,25 +76,26 @@ def activate_rules(self, imsi, msisdn: bytes, uplink_tunnel: int, ip_addr, apn_a
msisdn (bytes): subscriber MSISDN
uplink_tunnel(int): Tunnel ID of the subscriber session.
ip_addr (string): subscriber session ipv4 address
- dynamic_rules (PolicyRule []): list of dynamic rules to activate
+ policies (VersionedPolicies []): list of versioned policies to activate
"""
if self._datapath is None:
self.logger.error('Datapath not initialized for adding flows')
return ActivateFlowsResult(
- dynamic_rule_results=[RuleModResult(
- rule_id=rule.id,
+ policy_results=[RuleModResult(
+ rule_id=policy.rule.id,
+ version=policy.version,
result=RuleModResult.FAILURE,
- ) for rule in dynamic_rules],
+ ) for policy in policies],
)
- dyn_results = []
- for rule in dynamic_rules:
- res = self._install_flow_for_rule(imsi, msisdn, uplink_tunnel, ip_addr, apn_ambr, rule)
- dyn_results.append(RuleModResult(rule_id=rule.id, result=res))
+ policy_results = []
+ for policy in policies:
+ res = self._install_flow_for_rule(imsi, msisdn, uplink_tunnel, ip_addr, apn_ambr, policy.rule, policy.version)
+ policy_results.append(RuleModResult(rule_id=policy.rule.id, version=policy.version, result=res))
# Install a base flow for when no rule is matched.
self._install_default_flow_for_subscriber(imsi, ip_addr)
return ActivateFlowsResult(
- dynamic_rule_results=dyn_results,
+ policy_results=policy_results,
)
def _remove_he_flows(self, ip_addr: IPAddress, rule_id: str = "",
@@ -255,36 +267,55 @@ def _get_ue_specific_flow_msgs(self, requests: List[ActivateFlowsRequest]):
msg_list = []
for add_flow_req in requests:
imsi = add_flow_req.sid.id
- ip_addr = convert_ipv4_str_to_ip_proto(add_flow_req.ip_addr)
apn_ambr = add_flow_req.apn_ambr
- dynamic_rules = add_flow_req.dynamic_rules
+ policies = add_flow_req.policies
msisdn = add_flow_req.msisdn
uplink_tunnel = add_flow_req.uplink_tunnel
- msgs = self._get_default_flow_msgs_for_subscriber(imsi, ip_addr)
- if msgs:
- msg_list.extend(msgs)
+ if self._setup_type == 'CWF' or add_flow_req.ip_addr:
+ ipv4 = convert_ipv4_str_to_ip_proto(add_flow_req.ip_addr)
+ msgs = self._get_default_flow_msgs_for_subscriber(imsi, ipv4)
+ if msgs:
+ msg_list.extend(msgs)
+
+ for policy in policies:
+ msg_list.extend(self._get_policy_flows(imsi, msisdn, uplink_tunnel, ipv4, apn_ambr, policy))
+ if add_flow_req.ipv6_addr:
+ ipv6 = convert_ipv6_bytes_to_ip_proto(add_flow_req.ipv6_addr)
+ msgs = self._get_default_flow_msgs_for_subscriber(imsi, ipv6)
+ if msgs:
+ msg_list.extend(msgs)
+
+ for policy in policies:
+ msg_list.extend(self._get_policy_flows(imsi, msisdn, uplink_tunnel, ipv6, apn_ambr, policy))
- for rule in dynamic_rules:
- try:
- if rule.redirect.support == rule.redirect.ENABLED:
- continue
- flow_adds = self._get_rule_match_flow_msgs(imsi, msisdn, uplink_tunnel, ip_addr, apn_ambr, rule)
- msg_list.extend(flow_adds)
- except FlowMatchError:
- self.logger.error("Failed to verify rule_id: %s", rule.id)
return {self.tbl_num: msg_list}
+ def _get_policy_flows(self, imsi, msisdn, uplink_tunnel, ip_addr, apn_ambr,
+ policy):
+ msg_list = []
+ # As the versions are managed by sessiond, save state here
+ self._service_manager.session_rule_version_mapper.save_version(
+ imsi, ip_addr, policy.rule.id, policy.version)
+ try:
+ if policy.rule.redirect.support == policy.rule.redirect.ENABLED:
+ return msg_list
+ flow_adds = self._get_rule_match_flow_msgs(imsi, msisdn, uplink_tunnel, ip_addr, apn_ambr, policy.rule, policy.version)
+ msg_list.extend(flow_adds)
+ except FlowMatchError:
+ self.logger.error("Failed to verify rule_id: %s", policy.rule.id)
+ return msg_list
+
def _process_redirection_rules(self, requests):
for add_flow_req in requests:
imsi = add_flow_req.sid.id
ip_addr = convert_ipv4_str_to_ip_proto(add_flow_req.ip_addr)
- dynamic_rules = add_flow_req.dynamic_rules
+ policies = add_flow_req.policies
- for rule in dynamic_rules:
- if rule.redirect.support == rule.redirect.ENABLED:
- self._install_redirect_flow(imsi, ip_addr, rule)
+ for policy in policies:
+ if policy.rule.redirect.support == policy.rule.redirect.ENABLED:
+ self._install_redirect_flow(imsi, ip_addr, policy.rule, policy.version)
def finish_init(self, requests):
# For now just reinsert redirection rules, this is a bit of a hack but
@@ -300,7 +331,7 @@ def finish_init(self, requests):
@abstractmethod
- def _install_flow_for_rule(self, imsi, msisdn: bytes, uplink_tunnel: int, ip_addr, apn_ambr, rule):
+ def _install_flow_for_rule(self, imsi, msisdn: bytes, uplink_tunnel: int, ip_addr, apn_ambr, rule, version):
"""
Install a flow given a rule. Subclass should implement this.
@@ -323,7 +354,7 @@ def _install_default_flow_for_subscriber(self, imsi, ip_addr):
raise NotImplementedError
@abstractmethod
- def _install_redirect_flow(self, imsi, ip_addr, rule):
+ def _install_redirect_flow(self, imsi, ip_addr, rule, version):
"""
Install a redirection flow for the subscriber.
Subclass should implement this.
diff --git a/lte/gateway/python/magma/pipelined/app/restart_mixin.py b/lte/gateway/python/magma/pipelined/app/restart_mixin.py
index a83dbaaa3d3a..55968c041052 100644
--- a/lte/gateway/python/magma/pipelined/app/restart_mixin.py
+++ b/lte/gateway/python/magma/pipelined/app/restart_mixin.py
@@ -10,14 +10,13 @@
See the License for the specific language governing permissions and
limitations under the License.
"""
-from typing import List, Dict
from abc import ABCMeta, abstractmethod
+from typing import Dict, List
from lte.protos.pipelined_pb2 import SetupFlowsResult
from magma.pipelined.app.base import ControllerNotReadyException
from magma.pipelined.openflow import flows
from magma.pipelined.policy_converters import ovs_flow_match_to_magma_match
-
from ryu.ofproto.ofproto_v1_4_parser import OFPFlowStats
DefaultMsgsMap = Dict[int, List[OFPFlowStats]]
diff --git a/lte/gateway/python/magma/pipelined/app/startup_flows.py b/lte/gateway/python/magma/pipelined/app/startup_flows.py
index 7e3b53652303..86def2443c23 100644
--- a/lte/gateway/python/magma/pipelined/app/startup_flows.py
+++ b/lte/gateway/python/magma/pipelined/app/startup_flows.py
@@ -11,16 +11,18 @@
limitations under the License.
"""
-from ryu.lib import hub
+from magma.pipelined.app.base import (
+ ControllerNotReadyException,
+ ControllerType,
+ MagmaController,
+)
+from magma.pipelined.openflow import messages
+from magma.pipelined.openflow.exceptions import MagmaOFError
from ryu.controller import ofp_event
from ryu.controller.handler import MAIN_DISPATCHER, set_ev_cls
+from ryu.lib import hub
from ryu.ofproto.ofproto_v1_4 import OFPMPF_REPLY_MORE
-from magma.pipelined.app.base import ControllerNotReadyException, \
- MagmaController, ControllerType
-from magma.pipelined.openflow import messages
-from magma.pipelined.openflow.exceptions import MagmaOFError
-
class StartupFlows(MagmaController):
"""
diff --git a/lte/gateway/python/magma/pipelined/app/testing.py b/lte/gateway/python/magma/pipelined/app/testing.py
index e6fea1073b70..b47150fef17f 100644
--- a/lte/gateway/python/magma/pipelined/app/testing.py
+++ b/lte/gateway/python/magma/pipelined/app/testing.py
@@ -11,14 +11,12 @@
limitations under the License.
"""
-from magma.pipelined.openflow import flows
from magma.pipelined.app.base import MagmaController
-from magma.pipelined.openflow import messages
+from magma.pipelined.openflow import flows, messages
from magma.pipelined.openflow.exceptions import MagmaOFError
-
from ryu.controller import ofp_event
-from ryu.lib.ofctl_v1_4 import to_instructions
from ryu.controller.handler import MAIN_DISPATCHER, set_ev_cls
+from ryu.lib.ofctl_v1_4 import to_instructions
class TestingController(MagmaController):
diff --git a/lte/gateway/python/magma/pipelined/app/tunnel_learn.py b/lte/gateway/python/magma/pipelined/app/tunnel_learn.py
index 897f90b1cba1..ac06cd37a980 100644
--- a/lte/gateway/python/magma/pipelined/app/tunnel_learn.py
+++ b/lte/gateway/python/magma/pipelined/app/tunnel_learn.py
@@ -11,10 +11,10 @@
limitations under the License.
"""
-from .base import MagmaController, ControllerType
+from magma.pipelined.app.base import ControllerType, MagmaController
from magma.pipelined.openflow import flows
from magma.pipelined.openflow.magma_match import MagmaMatch
-from magma.pipelined.openflow.registers import Direction, DIRECTION_REG
+from magma.pipelined.openflow.registers import DIRECTION_REG, Direction
class TunnelLearnController(MagmaController):
diff --git a/lte/gateway/python/magma/pipelined/app/ue_mac.py b/lte/gateway/python/magma/pipelined/app/ue_mac.py
index 43cc42c25c83..b1a69ed8a908 100644
--- a/lte/gateway/python/magma/pipelined/app/ue_mac.py
+++ b/lte/gateway/python/magma/pipelined/app/ue_mac.py
@@ -13,24 +13,25 @@
import threading
from typing import List
-from ryu.controller import ofp_event
-from ryu.controller.handler import MAIN_DISPATCHER, set_ev_cls
-from ryu.lib.packet import packet
-from ryu.lib.packet import ether_types, dhcp
-from ryu.ofproto.inet import IPPROTO_TCP, IPPROTO_UDP
-
-from lte.protos.pipelined_pb2 import FlowResponse, SetupFlowsResult, \
- UEMacFlowRequest
-from magma.pipelined.app.base import MagmaController, ControllerType
+from lte.protos.pipelined_pb2 import (
+ FlowResponse,
+ SetupFlowsResult,
+ UEMacFlowRequest,
+)
+from magma.pipelined.app.base import ControllerType, MagmaController
from magma.pipelined.app.inout import INGRESS
-from magma.pipelined.directoryd_client import update_record
-from magma.pipelined.imsi import encode_imsi, decode_imsi
-from magma.pipelined.openflow import flows
from magma.pipelined.app.ipfix import IPFIXController
from magma.pipelined.bridge_util import BridgeTools
+from magma.pipelined.directoryd_client import update_record
+from magma.pipelined.imsi import decode_imsi, encode_imsi
+from magma.pipelined.openflow import flows
from magma.pipelined.openflow.exceptions import MagmaOFError
from magma.pipelined.openflow.magma_match import MagmaMatch
from magma.pipelined.openflow.registers import IMSI_REG, load_passthrough
+from ryu.controller import ofp_event
+from ryu.controller.handler import MAIN_DISPATCHER, set_ev_cls
+from ryu.lib.packet import dhcp, ether_types, packet
+from ryu.ofproto.inet import IPPROTO_TCP, IPPROTO_UDP
class UEMacAddressController(MagmaController):
diff --git a/lte/gateway/python/magma/pipelined/app/uplink_bridge.py b/lte/gateway/python/magma/pipelined/app/uplink_bridge.py
index ca0d039c9dfa..e2516a076de2 100644
--- a/lte/gateway/python/magma/pipelined/app/uplink_bridge.py
+++ b/lte/gateway/python/magma/pipelined/app/uplink_bridge.py
@@ -16,8 +16,7 @@
import netaddr
import netifaces
-
-from magma.pipelined.app.base import MagmaController, ControllerType
+from magma.pipelined.app.base import ControllerType, MagmaController
from magma.pipelined.bridge_util import BridgeTools
from magma.pipelined.openflow import flows
diff --git a/lte/gateway/python/magma/pipelined/app/vlan_learn.py b/lte/gateway/python/magma/pipelined/app/vlan_learn.py
index a99597f2223e..7b099be711d9 100644
--- a/lte/gateway/python/magma/pipelined/app/vlan_learn.py
+++ b/lte/gateway/python/magma/pipelined/app/vlan_learn.py
@@ -11,13 +11,17 @@
limitations under the License.
"""
-from .base import MagmaController, ControllerType
-from ryu.ofproto import ether
-from magma.pipelined.openflow import flows
+from magma.pipelined.app.base import ControllerType, MagmaController
from magma.pipelined.imsi import encode_imsi
+from magma.pipelined.openflow import flows
from magma.pipelined.openflow.magma_match import MagmaMatch
-from magma.pipelined.openflow.registers import Direction, DIRECTION_REG, \
- IMSI_REG, VLAN_TAG_REG
+from magma.pipelined.openflow.registers import (
+ DIRECTION_REG,
+ IMSI_REG,
+ VLAN_TAG_REG,
+ Direction,
+)
+from ryu.ofproto import ether
class VlanLearnController(MagmaController):
diff --git a/lte/gateway/python/magma/pipelined/app/xwf_passthru.py b/lte/gateway/python/magma/pipelined/app/xwf_passthru.py
index 95ad87668161..f8ffd3b10d77 100644
--- a/lte/gateway/python/magma/pipelined/app/xwf_passthru.py
+++ b/lte/gateway/python/magma/pipelined/app/xwf_passthru.py
@@ -10,12 +10,11 @@
See the License for the specific language governing permissions and
limitations under the License.
"""
+from magma.pipelined.app.base import ControllerType, MagmaController
from magma.pipelined.app.inout import INGRESS
from magma.pipelined.openflow import flows
from magma.pipelined.openflow.magma_match import MagmaMatch
-from .base import MagmaController, ControllerType
-
class XWFPassthruController(MagmaController):
diff --git a/lte/gateway/python/magma/pipelined/bridge_util.py b/lte/gateway/python/magma/pipelined/bridge_util.py
index 69424854eb5d..45e2d3e329b6 100644
--- a/lte/gateway/python/magma/pipelined/bridge_util.py
+++ b/lte/gateway/python/magma/pipelined/bridge_util.py
@@ -11,11 +11,11 @@
limitations under the License.
"""
import binascii
-from collections import defaultdict
-import re
import logging
+import re
import subprocess
-from typing import Optional, Dict, List, TYPE_CHECKING
+from collections import defaultdict
+from typing import TYPE_CHECKING, Dict, List, Optional
# Prevent circular import
if TYPE_CHECKING:
diff --git a/lte/gateway/python/magma/pipelined/directoryd_client.py b/lte/gateway/python/magma/pipelined/directoryd_client.py
index 0aab6ff7a6a6..bae19cc060e8 100644
--- a/lte/gateway/python/magma/pipelined/directoryd_client.py
+++ b/lte/gateway/python/magma/pipelined/directoryd_client.py
@@ -10,16 +10,17 @@
See the License for the specific language governing permissions and
limitations under the License.
"""
-import grpc
import logging
-from ryu.lib import hub
-
+import grpc
from magma.common.service_registry import ServiceRegistry
from orc8r.protos.common_pb2 import Void
-from orc8r.protos.directoryd_pb2 import UpdateRecordRequest, \
- GetDirectoryFieldRequest
+from orc8r.protos.directoryd_pb2 import (
+ GetDirectoryFieldRequest,
+ UpdateRecordRequest,
+)
from orc8r.protos.directoryd_pb2_grpc import GatewayDirectoryServiceStub
+from ryu.lib import hub
DIRECTORYD_SERVICE_NAME = "directoryd"
DEFAULT_GRPC_TIMEOUT = 10
diff --git a/lte/gateway/python/magma/pipelined/encoding.py b/lte/gateway/python/magma/pipelined/encoding.py
index 796b9973862a..b4a273a1ad14 100644
--- a/lte/gateway/python/magma/pipelined/encoding.py
+++ b/lte/gateway/python/magma/pipelined/encoding.py
@@ -11,12 +11,12 @@
limitations under the License.
"""
-import logging
import codecs
-import hashlib
import gzip
-from Crypto.Cipher import ARC4
-from Crypto.Cipher import AES
+import hashlib
+import logging
+
+from Crypto.Cipher import AES, ARC4
from Crypto.Hash import HMAC
from Crypto.Random import get_random_bytes
from lte.protos.mconfig.mconfigs_pb2 import PipelineD
diff --git a/lte/gateway/python/magma/pipelined/envoy_client.py b/lte/gateway/python/magma/pipelined/envoy_client.py
index f874bcd85c7b..4cf323642dd4 100644
--- a/lte/gateway/python/magma/pipelined/envoy_client.py
+++ b/lte/gateway/python/magma/pipelined/envoy_client.py
@@ -10,17 +10,20 @@
See the License for the specific language governing permissions and
limitations under the License.
"""
+import logging
from typing import List
import grpc
-import logging
-
-from magma.common.service_registry import ServiceRegistry
+from feg.protos.envoy_controller_pb2 import (
+ AddUEHeaderEnrichmentRequest,
+ AddUEHeaderEnrichmentResult,
+ DeactivateUEHeaderEnrichmentRequest,
+ DeactivateUEHeaderEnrichmentResult,
+ Header,
+)
from feg.protos.envoy_controller_pb2_grpc import EnvoyControllerStub
-from feg.protos.envoy_controller_pb2 import AddUEHeaderEnrichmentRequest, \
- DeactivateUEHeaderEnrichmentRequest, Header, AddUEHeaderEnrichmentResult, \
- DeactivateUEHeaderEnrichmentResult
from lte.protos.mobilityd_pb2 import IPAddress
+from magma.common.service_registry import ServiceRegistry
SERVICE_NAME = "envoy_controller"
IMSI_HDR = 'imsi'
diff --git a/lte/gateway/python/magma/pipelined/gtp_stats_collector.py b/lte/gateway/python/magma/pipelined/gtp_stats_collector.py
index f6fd98b67bc3..62f7cfafccfd 100644
--- a/lte/gateway/python/magma/pipelined/gtp_stats_collector.py
+++ b/lte/gateway/python/magma/pipelined/gtp_stats_collector.py
@@ -11,18 +11,17 @@
limitations under the License.
"""
-import logging
-
import asyncio
-from typing import List, NamedTuple, Optional
-
+import logging
import re
+from typing import List, NamedTuple, Optional
from magma.common.job import Job
from magma.magmad.check import subprocess_workflow
-
-from magma.pipelined.metrics import GTP_PORT_USER_PLANE_DL_BYTES, \
- GTP_PORT_USER_PLANE_UL_BYTES
+from magma.pipelined.metrics import (
+ GTP_PORT_USER_PLANE_DL_BYTES,
+ GTP_PORT_USER_PLANE_UL_BYTES,
+)
OVSDBDumpCommandParams = NamedTuple('OVSDBCommandParams',
[('table', str), ('columns', List[str])])
diff --git a/lte/gateway/python/magma/pipelined/ifaces.py b/lte/gateway/python/magma/pipelined/ifaces.py
index 559c62d2da91..be9e39d3ad07 100644
--- a/lte/gateway/python/magma/pipelined/ifaces.py
+++ b/lte/gateway/python/magma/pipelined/ifaces.py
@@ -11,8 +11,8 @@
limitations under the License.
"""
import asyncio
-import netifaces
+import netifaces
from magma.pipelined.metrics import NETWORK_IFACE_STATUS
POLL_INTERVAL_SECONDS = 3
diff --git a/lte/gateway/python/magma/pipelined/ipv6_prefix_store.py b/lte/gateway/python/magma/pipelined/ipv6_prefix_store.py
index 6e198097ccf1..e36a2238b7a7 100644
--- a/lte/gateway/python/magma/pipelined/ipv6_prefix_store.py
+++ b/lte/gateway/python/magma/pipelined/ipv6_prefix_store.py
@@ -10,13 +10,15 @@
See the License for the specific language governing permissions and
limitations under the License.
"""
-import threading
import ipaddress
+import threading
from magma.common.redis.client import get_default_client
from magma.common.redis.containers import RedisHashDict
-from magma.common.redis.serializers import get_json_deserializer, \
- get_json_serializer
+from magma.common.redis.serializers import (
+ get_json_deserializer,
+ get_json_serializer,
+)
class InterfaceIDToPrefixMapper:
diff --git a/lte/gateway/python/magma/pipelined/main.py b/lte/gateway/python/magma/pipelined/main.py
index 1c493d04d827..d2563a54f5ba 100644
--- a/lte/gateway/python/magma/pipelined/main.py
+++ b/lte/gateway/python/magma/pipelined/main.py
@@ -20,26 +20,26 @@
import threading
import aioeventlet
-from ryu import cfg
-from ryu.base.app_manager import AppManager
-from scapy.arch import get_if_hwaddr
-from ryu.ofproto.ofproto_v1_4 import OFPP_LOCAL
-
+from lte.protos.mconfig import mconfigs_pb2
from magma.common.misc_utils import call_process, get_ip_from_if
from magma.common.sentry import sentry_init
from magma.common.service import MagmaService
from magma.configuration import environment
from magma.pipelined.app import of_rest_server
+from magma.pipelined.app.he import PROXY_PORT_NAME
+from magma.pipelined.bridge_util import BridgeTools
from magma.pipelined.check_quota_server import run_flask
-from magma.pipelined.service_manager import ServiceManager
+from magma.pipelined.gtp_stats_collector import (
+ MIN_OVSDB_DUMP_POLLING_INTERVAL,
+ GTPStatsCollector,
+)
from magma.pipelined.ifaces import monitor_ifaces
from magma.pipelined.rpc_servicer import PipelinedRpcServicer
-from magma.pipelined.gtp_stats_collector import GTPStatsCollector, \
- MIN_OVSDB_DUMP_POLLING_INTERVAL
-
-from magma.pipelined.app.he import PROXY_PORT_NAME
-from magma.pipelined.bridge_util import BridgeTools
-from lte.protos.mconfig import mconfigs_pb2
+from magma.pipelined.service_manager import ServiceManager
+from ryu import cfg
+from ryu.base.app_manager import AppManager
+from ryu.ofproto.ofproto_v1_4 import OFPP_LOCAL
+from scapy.arch import get_if_hwaddr
def main():
diff --git a/lte/gateway/python/magma/pipelined/metrics.py b/lte/gateway/python/magma/pipelined/metrics.py
index efbb9ddd5c42..6e6fa61fcf08 100644
--- a/lte/gateway/python/magma/pipelined/metrics.py
+++ b/lte/gateway/python/magma/pipelined/metrics.py
@@ -13,7 +13,6 @@
from prometheus_client import Counter, Gauge
-
DP_SEND_MSG_ERROR = Counter('dp_send_msg_error',
'Total datapath message send errors', ['cause'])
ARP_DEFAULT_GW_MAC_ERROR = Counter('arp_default_gw_mac_error',
diff --git a/lte/gateway/python/magma/pipelined/mobilityd_client.py b/lte/gateway/python/magma/pipelined/mobilityd_client.py
index ec6188f14ec7..723adada3add 100644
--- a/lte/gateway/python/magma/pipelined/mobilityd_client.py
+++ b/lte/gateway/python/magma/pipelined/mobilityd_client.py
@@ -10,15 +10,14 @@
See the License for the specific language governing permissions and
limitations under the License.
"""
+import logging
from typing import List
import grpc
-import logging
-
+from lte.protos.mobilityd_pb2 import GWInfo, IPAddress
+from lte.protos.mobilityd_pb2_grpc import MobilityServiceStub
from magma.common.service_registry import ServiceRegistry
from orc8r.protos.common_pb2 import Void
-from lte.protos.mobilityd_pb2_grpc import MobilityServiceStub
-from lte.protos.mobilityd_pb2 import IPAddress, GWInfo
SERVICE_NAME = "mobilityd"
IPV4_ADDR_KEY = "ipv4_addr"
diff --git a/lte/gateway/python/magma/pipelined/ng_manager/node_state_manager.py b/lte/gateway/python/magma/pipelined/ng_manager/node_state_manager.py
index 88965a7a98e6..c3ad9ef4bd94 100644
--- a/lte/gateway/python/magma/pipelined/ng_manager/node_state_manager.py
+++ b/lte/gateway/python/magma/pipelined/ng_manager/node_state_manager.py
@@ -12,17 +12,19 @@
"""
import logging
-import netifaces
-from typing import NamedTuple, Dict
+from typing import Dict, NamedTuple
+import netifaces
+from google.protobuf.timestamp_pb2 import Timestamp
from lte.protos.session_manager_pb2 import (
- UPFNodeState,
UPFAssociationState,
UPFFeatureSet,
- UserPlaneIPResourceSchema)
-
-from google.protobuf.timestamp_pb2 import Timestamp
-from magma.pipelined.set_interface_client import send_node_state_association_request
+ UPFNodeState,
+ UserPlaneIPResourceSchema,
+)
+from magma.pipelined.set_interface_client import (
+ send_node_state_association_request,
+)
from ryu.lib import hub
EXP_BASE = 3
diff --git a/lte/gateway/python/magma/pipelined/ng_manager/session_state_manager.py b/lte/gateway/python/magma/pipelined/ng_manager/session_state_manager.py
index b821991e8f95..103132d5e9ef 100644
--- a/lte/gateway/python/magma/pipelined/ng_manager/session_state_manager.py
+++ b/lte/gateway/python/magma/pipelined/ng_manager/session_state_manager.py
@@ -11,26 +11,23 @@
limitations under the License.
"""
-from typing import (
- NamedTuple,
- Optional)
-
from enum import Enum
-from magma.pipelined.set_interface_client import (
- send_periodic_session_update)
-
-from magma.pipelined.ng_manager.session_state_manager_util import (
- pdr_create_rule_entry)
-
-from lte.protos.session_manager_pb2 import (
- UPFSessionConfigState,
- UPFSessionState)
+from typing import NamedTuple, Optional
from lte.protos.pipelined_pb2 import (
+ CauseIE,
+ OffendingIE,
PdrState,
UPFSessionContextState,
- OffendingIE,
- CauseIE)
+)
+from lte.protos.session_manager_pb2 import (
+ UPFSessionConfigState,
+ UPFSessionState,
+)
+from magma.pipelined.ng_manager.session_state_manager_util import (
+ pdr_create_rule_entry,
+)
+from magma.pipelined.set_interface_client import send_periodic_session_update
# Help to build failure report
MsgParseOutput = NamedTuple(
diff --git a/lte/gateway/python/magma/pipelined/ng_manager/session_state_manager_util.py b/lte/gateway/python/magma/pipelined/ng_manager/session_state_manager_util.py
index 709e55e9db6a..2121c9eb28d1 100644
--- a/lte/gateway/python/magma/pipelined/ng_manager/session_state_manager_util.py
+++ b/lte/gateway/python/magma/pipelined/ng_manager/session_state_manager_util.py
@@ -11,8 +11,11 @@
limitations under the License.
"""
from typing import NamedTuple
-from lte.protos.pipelined_pb2 import ActivateFlowsRequest, \
- DeactivateFlowsRequest
+
+from lte.protos.pipelined_pb2 import (
+ ActivateFlowsRequest,
+ DeactivateFlowsRequest,
+)
FARRuleEntry = NamedTuple(
'FARRuleEntry',
diff --git a/lte/gateway/python/magma/pipelined/openflow/flows.py b/lte/gateway/python/magma/pipelined/openflow/flows.py
index 19687ad86bf6..082dde241ba8 100644
--- a/lte/gateway/python/magma/pipelined/openflow/flows.py
+++ b/lte/gateway/python/magma/pipelined/openflow/flows.py
@@ -14,7 +14,7 @@
from magma.pipelined.openflow import messages
from magma.pipelined.openflow.magma_match import MagmaMatch
-from magma.pipelined.openflow.registers import SCRATCH_REGS, REG_ZERO_VAL
+from magma.pipelined.openflow.registers import REG_ZERO_VAL, SCRATCH_REGS
from ryu.ofproto.nicira_ext import ofs_nbits
logger = logging.getLogger(__name__)
diff --git a/lte/gateway/python/magma/pipelined/openflow/magma_match.py b/lte/gateway/python/magma/pipelined/openflow/magma_match.py
index ee3ae5946885..42c3f591de3d 100644
--- a/lte/gateway/python/magma/pipelined/openflow/magma_match.py
+++ b/lte/gateway/python/magma/pipelined/openflow/magma_match.py
@@ -12,9 +12,18 @@
"""
from typing import Optional
-from magma.pipelined.openflow.registers import IMSI_REG, DIRECTION_REG, \
- is_valid_direction, Direction, RULE_VERSION_REG, PASSTHROUGH_REG, \
- VLAN_TAG_REG, DPI_REG, RULE_NUM_REG, PROXY_TAG_REG
+from magma.pipelined.openflow.registers import (
+ DIRECTION_REG,
+ DPI_REG,
+ IMSI_REG,
+ PASSTHROUGH_REG,
+ PROXY_TAG_REG,
+ RULE_NUM_REG,
+ RULE_VERSION_REG,
+ VLAN_TAG_REG,
+ Direction,
+ is_valid_direction,
+)
class MagmaMatch(object):
@@ -77,4 +86,4 @@ def _check_args(self):
if k == DIRECTION_REG and self.direction:
raise Exception("Register %s should not be directly set" % k)
if k == IMSI_REG and self.imsi:
- raise Exception("Register %s should not be directly set" % k)
\ No newline at end of file
+ raise Exception("Register %s should not be directly set" % k)
diff --git a/lte/gateway/python/magma/pipelined/openflow/messages.py b/lte/gateway/python/magma/pipelined/openflow/messages.py
index a87707be7b35..5cd79caade80 100644
--- a/lte/gateway/python/magma/pipelined/openflow/messages.py
+++ b/lte/gateway/python/magma/pipelined/openflow/messages.py
@@ -15,15 +15,16 @@
# there's a cyclic dependency in ryu
import ryu.base.app_manager # pylint: disable=unused-import
+from magma.pipelined.metrics import DP_SEND_MSG_ERROR
+from magma.pipelined.openflow.exceptions import (
+ MagmaDPDisconnectedError,
+ MagmaOFError,
+)
+from magma.pipelined.policy_converters import MATCH_ATTRIBUTES
from ryu.controller.controller import Datapath
from ryu.lib import hub
from ryu.ofproto.ofproto_parser import MsgBase
-from magma.pipelined.openflow.exceptions import MagmaOFError,\
- MagmaDPDisconnectedError
-from magma.pipelined.metrics import DP_SEND_MSG_ERROR
-from magma.pipelined.policy_converters import MATCH_ATTRIBUTES
-
logger = logging.getLogger(__name__)
DEFAULT_TIMEOUT_SEC = 10
diff --git a/lte/gateway/python/magma/pipelined/openflow/meters.py b/lte/gateway/python/magma/pipelined/openflow/meters.py
index 1ddb62405a7f..dcf7f1f574ff 100644
--- a/lte/gateway/python/magma/pipelined/openflow/meters.py
+++ b/lte/gateway/python/magma/pipelined/openflow/meters.py
@@ -11,6 +11,7 @@
limitations under the License.
"""
import logging
+
from magma.pipelined.openflow import messages
LOG = logging.getLogger('openflow.meters')
diff --git a/lte/gateway/python/magma/pipelined/openflow/registers.py b/lte/gateway/python/magma/pipelined/openflow/registers.py
index 9d92d6b197e9..1fed5d906487 100644
--- a/lte/gateway/python/magma/pipelined/openflow/registers.py
+++ b/lte/gateway/python/magma/pipelined/openflow/registers.py
@@ -11,6 +11,7 @@
limitations under the License.
"""
from enum import IntEnum
+
from magma.pipelined.imsi import encode_imsi
# Register names
diff --git a/lte/gateway/python/magma/pipelined/openflow/tests/test_msg_hub.py b/lte/gateway/python/magma/pipelined/openflow/tests/test_msg_hub.py
index 10cebc1afc67..6864e2981a71 100644
--- a/lte/gateway/python/magma/pipelined/openflow/tests/test_msg_hub.py
+++ b/lte/gateway/python/magma/pipelined/openflow/tests/test_msg_hub.py
@@ -13,11 +13,10 @@
import logging
import unittest
-from unittest.mock import Mock, MagicMock
-
-from ryu.lib import hub
+from unittest.mock import MagicMock, Mock
from magma.pipelined.openflow.messages import MessageHub
+from ryu.lib import hub
class MockBarrierRequest(object):
diff --git a/lte/gateway/python/magma/pipelined/policy_converters.py b/lte/gateway/python/magma/pipelined/policy_converters.py
index 762e49e95049..2c6cacf648dc 100644
--- a/lte/gateway/python/magma/pipelined/policy_converters.py
+++ b/lte/gateway/python/magma/pipelined/policy_converters.py
@@ -12,14 +12,16 @@
"""
import ipaddress
-from lte.protos.policydb_pb2 import FlowMatch
from lte.protos.mobilityd_pb2 import IPAddress
+from lte.protos.policydb_pb2 import FlowMatch
from magma.pipelined.openflow.magma_match import MagmaMatch
-from magma.pipelined.openflow.registers import Direction, load_direction, \
- DPI_REG
+from magma.pipelined.openflow.registers import (
+ DPI_REG,
+ Direction,
+ load_direction,
+)
from ryu.lib.packet import ether_types
-
MATCH_ATTRIBUTES = ['metadata', 'reg0', 'reg1', 'reg2', 'reg3', 'reg4', 'reg5',
'reg6', 'reg8', 'reg9', 'reg10',
'in_port', 'dl_vlan', 'vlan_tci',
@@ -262,4 +264,4 @@ def ovs_flow_match_to_magma_match(flow):
val = flow.match.get(a, None)
if val:
attribute_dict[a] = val
- return MagmaMatch(**attribute_dict)
\ No newline at end of file
+ return MagmaMatch(**attribute_dict)
diff --git a/lte/gateway/python/magma/pipelined/qos/common.py b/lte/gateway/python/magma/pipelined/qos/common.py
index beed77221aae..be7bfc676fef 100644
--- a/lte/gateway/python/magma/pipelined/qos/common.py
+++ b/lte/gateway/python/magma/pipelined/qos/common.py
@@ -10,20 +10,27 @@
See the License for the specific language governing permissions and
limitations under the License.
"""
-from typing import List, Dict # noqa
-
-import logging
import json
+import logging
+import threading
+import traceback
from enum import Enum
+from typing import Dict, List # noqa
+
from lte.protos.policydb_pb2 import FlowMatch
+from magma.configuration.service_configs import load_service_config
from magma.pipelined.qos.qos_meter_impl import MeterManager
from magma.pipelined.qos.qos_tc_impl import TCManager, TrafficClass
-from magma.pipelined.qos.types import QosInfo, get_key_json, get_key, get_subscriber_key,\
- get_subscriber_data, get_data_json, get_data
+from magma.pipelined.qos.types import (
+ QosInfo,
+ get_data,
+ get_data_json,
+ get_key,
+ get_key_json,
+ get_subscriber_data,
+ get_subscriber_key,
+)
from magma.pipelined.qos.utils import QosStore
-from magma.configuration.service_configs import load_service_config
-import traceback
-import threading
LOG = logging.getLogger("pipelined.qos.common")
# LOG.setLevel(logging.DEBUG)
diff --git a/lte/gateway/python/magma/pipelined/qos/qos_meter_impl.py b/lte/gateway/python/magma/pipelined/qos/qos_meter_impl.py
index a33fbf82f6b1..07e4f8f496db 100644
--- a/lte/gateway/python/magma/pipelined/qos/qos_meter_impl.py
+++ b/lte/gateway/python/magma/pipelined/qos/qos_meter_impl.py
@@ -11,10 +11,12 @@
limitations under the License.
"""
import logging
+import subprocess
+
from magma.pipelined.openflow.meters import MeterClass
-from .utils import IdManager
+
from .types import QosInfo
-import subprocess
+from .utils import IdManager
LOG = logging.getLogger('pipelined.qos.qos_meter_impl')
BROKEN_KERN_ERROR_MSG = "kernel module has a broken meter implementation"
diff --git a/lte/gateway/python/magma/pipelined/qos/qos_tc_impl.py b/lte/gateway/python/magma/pipelined/qos/qos_tc_impl.py
index 8f8235140783..80a116124e83 100644
--- a/lte/gateway/python/magma/pipelined/qos/qos_tc_impl.py
+++ b/lte/gateway/python/magma/pipelined/qos/qos_tc_impl.py
@@ -10,14 +10,16 @@
See the License for the specific language governing permissions and
limitations under the License.
"""
-from typing import Optional # noqa
-import subprocess
import logging
+import subprocess
+from typing import Optional # noqa
+
from lte.protos.policydb_pb2 import FlowMatch
+
+from .tc_ops_cmd import TcOpsCmd, argSplit, run_cmd
+from .tc_ops_pyroute2 import TcOpsPyRoute2
from .types import QosInfo
from .utils import IdManager
-from .tc_ops_cmd import run_cmd, TcOpsCmd, argSplit
-from .tc_ops_pyroute2 import TcOpsPyRoute2
LOG = logging.getLogger('pipelined.qos.qos_tc_impl')
# LOG.setLevel(logging.DEBUG)
diff --git a/lte/gateway/python/magma/pipelined/qos/tc_ops.py b/lte/gateway/python/magma/pipelined/qos/tc_ops.py
index 9c6565098442..ce6a4c03daae 100644
--- a/lte/gateway/python/magma/pipelined/qos/tc_ops.py
+++ b/lte/gateway/python/magma/pipelined/qos/tc_ops.py
@@ -11,8 +11,12 @@
limitations under the License.
"""
-from __future__ import absolute_import, division, print_function, \
- unicode_literals
+from __future__ import (
+ absolute_import,
+ division,
+ print_function,
+ unicode_literals,
+)
from abc import ABC, abstractmethod
diff --git a/lte/gateway/python/magma/pipelined/qos/tc_ops_cmd.py b/lte/gateway/python/magma/pipelined/qos/tc_ops_cmd.py
index e1d848e9a696..9dfc238deb9c 100644
--- a/lte/gateway/python/magma/pipelined/qos/tc_ops_cmd.py
+++ b/lte/gateway/python/magma/pipelined/qos/tc_ops_cmd.py
@@ -12,12 +12,13 @@
"""
-from .tc_ops import TcOpsBase
+import logging
import os
import shlex
import subprocess
from typing import List # noqa
-import logging
+
+from .tc_ops import TcOpsBase
LOG = logging.getLogger('pipelined.qos.tc_cmd')
diff --git a/lte/gateway/python/magma/pipelined/qos/tc_ops_pyroute2.py b/lte/gateway/python/magma/pipelined/qos/tc_ops_pyroute2.py
index 8ad170da32d8..d5a0bbce7f3e 100644
--- a/lte/gateway/python/magma/pipelined/qos/tc_ops_pyroute2.py
+++ b/lte/gateway/python/magma/pipelined/qos/tc_ops_pyroute2.py
@@ -12,11 +12,13 @@
"""
-from .tc_ops import TcOpsBase
import logging
-from pyroute2 import IPRoute, NetlinkError
import pprint
+from pyroute2 import IPRoute, NetlinkError
+
+from .tc_ops import TcOpsBase
+
LOG = logging.getLogger('pipelined.qos.tc_pyroute2')
QUEUE_PREFIX = '1:'
diff --git a/lte/gateway/python/magma/pipelined/qos/utils.py b/lte/gateway/python/magma/pipelined/qos/utils.py
index 8feb001e56fc..00b70ba68532 100644
--- a/lte/gateway/python/magma/pipelined/qos/utils.py
+++ b/lte/gateway/python/magma/pipelined/qos/utils.py
@@ -13,10 +13,13 @@
import logging
from collections import deque
+
from magma.common.redis.client import get_default_client
from magma.common.redis.containers import RedisHashDict
-from magma.common.redis.serializers import get_json_serializer, \
- get_json_deserializer
+from magma.common.redis.serializers import (
+ get_json_deserializer,
+ get_json_serializer,
+)
LOG = logging.getLogger('pipelined.qos.id_manager')
diff --git a/lte/gateway/python/magma/pipelined/redirect.py b/lte/gateway/python/magma/pipelined/redirect.py
index 59cc7f2eda7a..21958f9f6b2b 100644
--- a/lte/gateway/python/magma/pipelined/redirect.py
+++ b/lte/gateway/python/magma/pipelined/redirect.py
@@ -11,23 +11,29 @@
limitations under the License.
"""
-import netifaces
-import aiodns
import asyncio
import ipaddress
from collections import namedtuple
-from redis import RedisError
from urllib.parse import urlsplit
-from memoize import Memoizer
+import aiodns
+import netifaces
from magma.configuration.service_configs import get_service_config_value
from magma.pipelined.imsi import encode_imsi
from magma.pipelined.openflow import flows
from magma.pipelined.openflow.magma_match import MagmaMatch
-from magma.pipelined.openflow.registers import IMSI_REG, DIRECTION_REG, \
- Direction, SCRATCH_REGS, REG_ZERO_VAL, RULE_VERSION_REG, RULE_NUM_REG
+from magma.pipelined.openflow.registers import (
+ DIRECTION_REG,
+ IMSI_REG,
+ REG_ZERO_VAL,
+ RULE_NUM_REG,
+ RULE_VERSION_REG,
+ SCRATCH_REGS,
+ Direction,
+)
from magma.redirectd.redirect_store import RedirectDict
-
+from memoize import Memoizer
+from redis import RedisError
from ryu.lib.packet import ether_types
from ryu.ofproto.inet import IPPROTO_TCP, IPPROTO_UDP
from ryu.ofproto.ofproto_v1_4 import OFPP_LOCAL
diff --git a/lte/gateway/python/magma/pipelined/rpc_servicer.py b/lte/gateway/python/magma/pipelined/rpc_servicer.py
index 3b25c81cd5cb..1674abd4e55b 100644
--- a/lte/gateway/python/magma/pipelined/rpc_servicer.py
+++ b/lte/gateway/python/magma/pipelined/rpc_servicer.py
@@ -10,58 +10,63 @@
See the License for the specific language governing permissions and
limitations under the License.
"""
-import os
-import logging
import concurrent.futures
+import logging
+import os
import queue
-from functools import partial
+from collections import OrderedDict
from concurrent.futures import Future
from typing import List, Tuple
-from collections import OrderedDict
import grpc
from lte.protos import pipelined_pb2_grpc
+from lte.protos.mobilityd_pb2 import IPAddress
from lte.protos.pipelined_pb2 import (
- SetupFlowsResult,
- RequestOriginType,
+ ActivateFlowsRequest,
ActivateFlowsResult,
- DeactivateFlowsResult,
+ AllTableAssignments,
+ CauseIE,
DeactivateFlowsRequest,
+ DeactivateFlowsResult,
FlowResponse,
+ OffendingIE,
+ PdrState,
+ RequestOriginType,
RuleModResult,
- SetupUEMacRequest,
+ SessionSet,
+ SetupFlowsResult,
SetupPolicyRequest,
SetupQuotaRequest,
- ActivateFlowsRequest,
- AllTableAssignments,
+ SetupUEMacRequest,
TableAssignment,
- SessionSet,
- PdrState,
UPFSessionContextState,
- OffendingIE,
- CauseIE)
-from lte.protos.policydb_pb2 import PolicyRule
-from lte.protos.mobilityd_pb2 import IPAddress
-from lte.protos.subscriberdb_pb2 import AggregatedMaximumBitrate
+ VersionedPolicy,
+)
from lte.protos.session_manager_pb2 import RuleRecordTable
+from lte.protos.subscriberdb_pb2 import AggregatedMaximumBitrate
+from magma.pipelined.app.check_quota import CheckQuotaController
from magma.pipelined.app.dpi import DPIController
from magma.pipelined.app.enforcement import EnforcementController
from magma.pipelined.app.enforcement_stats import EnforcementStatsController
-from magma.pipelined.app.ue_mac import UEMacAddressController
from magma.pipelined.app.ipfix import IPFIXController
-from magma.pipelined.app.check_quota import CheckQuotaController
-from magma.pipelined.app.vlan_learn import VlanLearnController
+from magma.pipelined.app.ng_services import NGServiceController
from magma.pipelined.app.tunnel_learn import TunnelLearnController
-from magma.pipelined.policy_converters import convert_ipv4_str_to_ip_proto, \
- convert_ipv6_bytes_to_ip_proto
-from magma.pipelined.ipv6_prefix_store import get_ipv6_interface_id, get_ipv6_prefix
+from magma.pipelined.app.ue_mac import UEMacAddressController
+from magma.pipelined.app.vlan_learn import VlanLearnController
+from magma.pipelined.imsi import encode_imsi
+from magma.pipelined.ipv6_prefix_store import (
+ get_ipv6_interface_id,
+ get_ipv6_prefix,
+)
from magma.pipelined.metrics import (
- ENFORCEMENT_STATS_RULE_INSTALL_FAIL,
ENFORCEMENT_RULE_INSTALL_FAIL,
+ ENFORCEMENT_STATS_RULE_INSTALL_FAIL,
)
-from magma.pipelined.imsi import encode_imsi
from magma.pipelined.ng_manager.session_state_manager_util import PDRRuleEntry
-from magma.pipelined.app.ng_services import NGServiceController
+from magma.pipelined.policy_converters import (
+ convert_ipv4_str_to_ip_proto,
+ convert_ipv6_bytes_to_ip_proto,
+)
grpc_msg_queue = queue.Queue()
DEFAULT_CALL_TIMEOUT = 15
@@ -214,27 +219,25 @@ def _update_version(self, request: ActivateFlowsRequest, ipv4: IPAddress):
"""
Update version for a given subscriber and rule.
"""
- for rule in request.dynamic_rules:
- self._service_manager.session_rule_version_mapper.update_version(
- request.sid.id, ipv4, rule.id)
+ for policy in request.policies:
+ self._service_manager.session_rule_version_mapper.save_version(
+ request.sid.id, ipv4, policy.rule.id, policy.version)
def _remove_version(self, request: DeactivateFlowsRequest, ip_address: str):
- def cleanup_redis(imsi, ip_address, rule_id, version):
+ def cleanup_dict(imsi, ip_address, rule_id, version):
self._service_manager.session_rule_version_mapper \
.remove(imsi, ip_address, rule_id, version)
+ if not request.policies:
+ self._service_manager.session_rule_version_mapper\
+ .update_all_ue_versions(request.sid.id, ip_address)
+ return
- for rule_id in request.rule_ids:
+ for policy in request.policies:
self._service_manager.session_rule_version_mapper \
- .update_version(request.sid.id, ip_address,
- rule_id)
- version = self._service_manager.session_rule_version_mapper \
- .get_version(request.sid.id, ip_address, rule_id)
-
- # Give it sometime to cleanup enf stats
- self._loop.call_later(
- self._service_config['enforcement']['poll_interval'] * 2,
- partial(cleanup_redis, request.sid.id, ip_address, rule_id,
- version))
+ .save_version(request.sid.id, ip_address,
+ policy.rule_id, policy.version)
+ cleanup_dict(request.sid.id, ip_address, policy.rule_id,
+ policy.version)
def _activate_flows(self, request: ActivateFlowsRequest,
fut: 'Future[ActivateFlowsResult]'
@@ -251,7 +254,7 @@ def _activate_flows(self, request: ActivateFlowsRequest,
ret_ipv4 = self._install_flows_gx(request, ipv4)
else:
ret_ipv4 = self._install_flows_gy(request, ipv4)
- ret.dynamic_rule_results.extend(ret_ipv4.dynamic_rule_results)
+ ret.policy_results.extend(ret_ipv4.policy_results)
if request.ipv6_addr:
ipv6 = convert_ipv6_bytes_to_ip_proto(request.ipv6_addr)
self._update_ipv6_prefix_store(request.ipv6_addr)
@@ -259,7 +262,7 @@ def _activate_flows(self, request: ActivateFlowsRequest,
ret_ipv6 = self._install_flows_gx(request, ipv6)
else:
ret_ipv6 = self._install_flows_gy(request, ipv6)
- ret.dynamic_rule_results.extend(ret_ipv6.dynamic_rule_results)
+ ret.policy_results.extend(ret_ipv6.policy_results)
if request.uplink_tunnel and request.downlink_tunnel:
self._update_tunnel_map_store(request.uplink_tunnel,
request.downlink_tunnel)
@@ -281,21 +284,21 @@ def _install_flows_gx(self, request: ActivateFlowsRequest,
# Install rules in enforcement stats
enforcement_stats_res = self._activate_rules_in_enforcement_stats(
request.sid.id, request.msisdn, request.uplink_tunnel, ip_address, request.apn_ambr,
- request.dynamic_rules)
+ request.policies)
- failed_dynamic_rule_results = \
+ failed_policies_results = \
_retrieve_failed_results(enforcement_stats_res)
# Do not install any rules that failed to install in enforcement_stats.
- dynamic_rules = \
- _filter_failed_dynamic_rules(request, failed_dynamic_rule_results)
+ policies = \
+ _filter_failed_policies(request, failed_policies_results)
enforcement_res = self._activate_rules_in_enforcement(
request.sid.id, request.msisdn, request.uplink_tunnel, ip_address, request.apn_ambr,
- dynamic_rules)
+ policies)
# Include the failed rules from enforcement_stats in the response.
- enforcement_res.dynamic_rule_results.extend(
- failed_dynamic_rule_results)
+ enforcement_res.policy_results.extend(
+ failed_policies_results)
return enforcement_res
def _install_flows_gy(self, request: ActivateFlowsRequest,
@@ -313,20 +316,20 @@ def _install_flows_gy(self, request: ActivateFlowsRequest,
# Install rules in enforcement stats
enforcement_stats_res = self._activate_rules_in_enforcement_stats(
request.sid.id, request.msisdn, request.uplink_tunnel, ip_address, request.apn_ambr,
- request.dynamic_rules)
+ request.policies)
- failed_dynamic_rule_results = \
+ failed_policies_results = \
_retrieve_failed_results(enforcement_stats_res)
# Do not install any rules that failed to install in enforcement_stats.
- dynamic_rules = \
- _filter_failed_dynamic_rules(request, failed_dynamic_rule_results)
+ policies = \
+ _filter_failed_policies(request, failed_policies_results)
gy_res = self._activate_rules_in_gy(request.sid.id, request.msisdn, request.uplink_tunnel,
ip_address, request.apn_ambr,
- dynamic_rules)
+ policies)
# Include the failed rules from enforcement_stats in the response.
- gy_res.dynamic_rule_results.extend(failed_dynamic_rule_results)
+ gy_res.policy_results.extend(failed_policies_results)
return gy_res
def _activate_rules_in_enforcement_stats(self, imsi: str,
@@ -334,14 +337,14 @@ def _activate_rules_in_enforcement_stats(self, imsi: str,
uplink_tunnel: int,
ip_addr: IPAddress,
apn_ambr: AggregatedMaximumBitrate,
- dynamic_rules: List[PolicyRule]
+ policies: List[VersionedPolicy]
) -> ActivateFlowsResult:
if not self._service_manager.is_app_enabled(
EnforcementStatsController.APP_NAME):
return ActivateFlowsResult()
enforcement_stats_res = self._enforcement_stats.activate_rules(
- imsi, msisdn, uplink_tunnel, ip_addr, apn_ambr, dynamic_rules)
+ imsi, msisdn, uplink_tunnel, ip_addr, apn_ambr, policies)
_report_enforcement_stats_failures(enforcement_stats_res, imsi)
return enforcement_stats_res
@@ -349,12 +352,12 @@ def _activate_rules_in_enforcement(self, imsi: str, msisdn: bytes,
uplink_tunnel: int,
ip_addr: IPAddress,
apn_ambr: AggregatedMaximumBitrate,
- dynamic_rules: List[PolicyRule]
+ policies: List[VersionedPolicy]
) -> ActivateFlowsResult:
# TODO: this will crash pipelined if called with both static rules
# and dynamic rules at the same time
enforcement_res = self._enforcer_app.activate_rules(
- imsi, msisdn, uplink_tunnel, ip_addr, apn_ambr, dynamic_rules)
+ imsi, msisdn, uplink_tunnel, ip_addr, apn_ambr, policies)
# TODO ?? Should the enforcement failure be reported per imsi session
_report_enforcement_failures(enforcement_res, imsi)
return enforcement_res
@@ -363,11 +366,11 @@ def _activate_rules_in_gy(self, imsi: str, msisdn: bytes,
uplink_tunnel: int,
ip_addr: IPAddress,
apn_ambr: AggregatedMaximumBitrate,
- dynamic_rules: List[PolicyRule]
+ policies: List[VersionedPolicy]
) -> ActivateFlowsResult:
gy_res = self._gy_app.activate_rules(imsi, msisdn, uplink_tunnel,
ip_addr, apn_ambr,
- dynamic_rules)
+ policies)
# TODO: add metrics
return gy_res
@@ -415,26 +418,21 @@ def _deactivate_flows(self, request):
def _deactivate_flows_gx(self, request, ip_address: IPAddress):
logging.debug('Deactivating GX flows for %s', request.sid.id)
- if request.rule_ids:
- self._remove_version(request, ip_address)
- else:
- # TODO cleanup redis?
- # If no rule ids are given, all flows are deactivated
- self._service_manager.session_rule_version_mapper.update_version(
- request.sid.id, ip_address)
+ self._remove_version(request, ip_address)
if request.remove_default_drop_flows:
self._enforcement_stats.deactivate_default_flow(request.sid.id,
ip_address)
+ rule_ids = [policy.rule_id for policy in request.policies]
self._enforcer_app.deactivate_rules(request.sid.id, ip_address,
- request.rule_ids)
+ rule_ids)
def _deactivate_flows_gy(self, request, ip_address: IPAddress):
logging.debug('Deactivating GY flows for %s', request.sid.id)
# Only deactivate requested rules here to not affect GX
- if request.rule_ids:
- self._remove_version(request, ip_address)
+ self._remove_version(request, ip_address)
+ rule_ids = [policy.rule_id for policy in request.policies]
self._gy_app.deactivate_rules(request.sid.id, ip_address,
- request.rule_ids)
+ rule_ids)
def GetPolicyUsage(self, request, context):
"""
@@ -801,24 +799,24 @@ def _ng_tunnel_update(self, pdr_entry: PDRRuleEntry, subscriber_id: str) -> bool
def _retrieve_failed_results(activate_flow_result: ActivateFlowsResult
) -> Tuple[List[RuleModResult],
List[RuleModResult]]:
- failed_dynamic_rule_results = \
+ failed_policies_results = \
[result for result in
- activate_flow_result.dynamic_rule_results if
+ activate_flow_result.policy_results if
result.result == RuleModResult.FAILURE]
- return failed_dynamic_rule_results
+ return failed_policies_results
-def _filter_failed_dynamic_rules(request: ActivateFlowsRequest,
- failed_results: List[RuleModResult]
- ) -> List[PolicyRule]:
- failed_dynamic_rule_ids = [result.rule_id for result in failed_results]
- return [rule for rule in request.dynamic_rules if
- rule.id not in failed_dynamic_rule_ids]
+def _filter_failed_policies(request: ActivateFlowsRequest,
+ failed_results: List[RuleModResult]
+ ) -> List[VersionedPolicy]:
+ failed_policies = [result.rule_id for result in failed_results]
+ return [policy for policy in request.policies if
+ policy.rule.id not in failed_policies]
def _report_enforcement_failures(activate_flow_result: ActivateFlowsResult,
imsi: str):
- for result in activate_flow_result.dynamic_rule_results:
+ for result in activate_flow_result.policy_results:
if result.result == RuleModResult.SUCCESS:
continue
ENFORCEMENT_RULE_INSTALL_FAIL.labels(rule_id=result.rule_id,
@@ -828,7 +826,7 @@ def _report_enforcement_failures(activate_flow_result: ActivateFlowsResult,
def _report_enforcement_stats_failures(
activate_flow_result: ActivateFlowsResult,
imsi: str):
- for result in activate_flow_result.dynamic_rule_results:
+ for result in activate_flow_result.policy_results:
if result.result == RuleModResult.SUCCESS:
continue
ENFORCEMENT_STATS_RULE_INSTALL_FAIL.labels(rule_id=result.rule_id,
diff --git a/lte/gateway/python/magma/pipelined/rule_mappers.py b/lte/gateway/python/magma/pipelined/rule_mappers.py
index 203c3a194549..aab336d63f43 100644
--- a/lte/gateway/python/magma/pipelined/rule_mappers.py
+++ b/lte/gateway/python/magma/pipelined/rule_mappers.py
@@ -13,16 +13,16 @@
import json
import threading
from collections import namedtuple
-from typing import Optional
from lte.protos.mobilityd_pb2 import IPAddress
-from magma.pipelined.imsi import encode_imsi
from magma.common.redis.client import get_default_client
from magma.common.redis.containers import RedisFlatDict, RedisHashDict
-from magma.common.redis.serializers import get_json_deserializer, \
- get_json_serializer
-from magma.common.redis.serializers import RedisSerde
-
+from magma.common.redis.serializers import (
+ RedisSerde,
+ get_json_deserializer,
+ get_json_serializer,
+)
+from magma.pipelined.imsi import encode_imsi
SubscriberRuleKey = namedtuple('SubscriberRuleKey', 'key_type imsi ip_addr rule_id')
@@ -84,25 +84,16 @@ class SessionRuleToVersionMapper:
multiple threads.
"""
- VERSION_LIMIT = 0xFFFFFFFF # 32 bit unsigned int limit (inclusive)
-
def __init__(self):
self._version_by_imsi_and_rule = {}
self._lock = threading.Lock() # write lock
- def setup_redis(self):
- self._version_by_imsi_and_rule = RuleVersionDict()
-
- def _update_version_unsafe(self, imsi: str, ip_addr: str, rule_id: str):
+ def _save_version_unsafe(self, imsi: str, ip_addr: str, rule_id: str,
+ version):
key = self._get_json_key(encode_imsi(imsi), ip_addr, rule_id)
- version = self._version_by_imsi_and_rule.get(key)
- if not version:
- version = 0
- self._version_by_imsi_and_rule[key] = \
- (version % self.VERSION_LIMIT) + 1
-
- def update_version(self, imsi: str, ip_addr: IPAddress,
- rule_id: Optional[str] = None):
+ self._version_by_imsi_and_rule[key] = version
+
+ def update_all_ue_versions(self, imsi: str, ip_addr: IPAddress):
"""
Increment the version number for a given subscriber and rule. If the
rule id is not specified, then all rules for the subscriber will be
@@ -114,13 +105,24 @@ def update_version(self, imsi: str, ip_addr: IPAddress,
else:
ip_addr_str = ip_addr.address.decode('utf-8').strip()
with self._lock:
- if rule_id is None:
- for k, v in self._version_by_imsi_and_rule.items():
- _, imsi, ip_addr_str, _ = SubscriberRuleKey(*json.loads(k))
- if imsi == encoded_imsi and ip_addr_str == ip_addr_str:
- self._version_by_imsi_and_rule[k] = v + 1
- else:
- self._update_version_unsafe(imsi, ip_addr_str, rule_id)
+ for k, v in self._version_by_imsi_and_rule.items():
+ _, imsi, ip_addr_str, _ = SubscriberRuleKey(*json.loads(k))
+ if imsi == encoded_imsi and ip_addr_str == ip_addr_str:
+ self._version_by_imsi_and_rule[k] = v + 1
+
+ def save_version(self, imsi: str, ip_addr: IPAddress,
+ rule_id: [str], version: int):
+ """
+ Increment the version number for a given subscriber and rule. If the
+ rule id is not specified, then all rules for the subscriber will be
+ incremented.
+ """
+ if ip_addr is None or ip_addr.address is None:
+ ip_addr_str = ""
+ else:
+ ip_addr_str = ip_addr.address.decode('utf-8').strip()
+ with self._lock:
+ self._save_version_unsafe(imsi, ip_addr_str, rule_id, version)
def get_version(self, imsi: str, ip_addr: IPAddress, rule_id: str) -> int:
"""
diff --git a/lte/gateway/python/magma/pipelined/service_manager.py b/lte/gateway/python/magma/pipelined/service_manager.py
index d18e3c17b61d..ef937761b832 100644
--- a/lte/gateway/python/magma/pipelined/service_manager.py
+++ b/lte/gateway/python/magma/pipelined/service_manager.py
@@ -32,11 +32,11 @@
# pylint does not play well with aioeventlet, as it uses asyncio.async which
# produces a parse error
-import time
import asyncio
import logging
+import time
+from collections import OrderedDict, namedtuple
from concurrent.futures import Future
-from collections import namedtuple, OrderedDict
from typing import List
import aioeventlet
@@ -44,44 +44,48 @@
from lte.protos.mobilityd_pb2_grpc import MobilityServiceStub
from lte.protos.session_manager_pb2_grpc import (
LocalSessionManagerStub,
- SetInterfaceForUserPlaneStub)
-from magma.pipelined.app.base import ControllerType
+ SetInterfaceForUserPlaneStub,
+)
+from magma.common.service import MagmaService
+from magma.common.service_registry import ServiceRegistry
+from magma.configuration import environment
from magma.pipelined.app import of_rest_server
from magma.pipelined.app.access_control import AccessControlController
-from magma.pipelined.app.conntrack import ConntrackController
-from magma.pipelined.app.tunnel_learn import TunnelLearnController
-from magma.pipelined.app.vlan_learn import VlanLearnController
from magma.pipelined.app.arp import ArpController
-from magma.pipelined.app.ipv6_solicitation import \
- IPV6SolicitationController
+from magma.pipelined.app.base import ControllerType
+from magma.pipelined.app.check_quota import CheckQuotaController
+from magma.pipelined.app.classifier import Classifier
+from magma.pipelined.app.conntrack import ConntrackController
from magma.pipelined.app.dpi import DPIController
-from magma.pipelined.app.gy import GYController
from magma.pipelined.app.enforcement import EnforcementController
+from magma.pipelined.app.enforcement_stats import EnforcementStatsController
+from magma.pipelined.app.gy import GYController
+from magma.pipelined.app.he import HeaderEnrichmentController
+from magma.pipelined.app.inout import (
+ EGRESS,
+ INGRESS,
+ PHYSICAL_TO_LOGICAL,
+ InOutController,
+)
from magma.pipelined.app.ipfix import IPFIXController
+from magma.pipelined.app.ipv6_solicitation import IPV6SolicitationController
from magma.pipelined.app.li_mirror import LIMirrorController
-from magma.pipelined.app.enforcement_stats import EnforcementStatsController
-from magma.pipelined.app.inout import EGRESS, INGRESS, PHYSICAL_TO_LOGICAL, \
- InOutController
-from magma.pipelined.app.ue_mac import UEMacAddressController
-from magma.pipelined.app.xwf_passthru import XWFPassthruController
+from magma.pipelined.app.ng_services import NGServiceController
from magma.pipelined.app.startup_flows import StartupFlows
-from magma.pipelined.app.check_quota import CheckQuotaController
+from magma.pipelined.app.tunnel_learn import TunnelLearnController
+from magma.pipelined.app.ue_mac import UEMacAddressController
from magma.pipelined.app.uplink_bridge import UplinkBridgeController
-from magma.pipelined.app.ng_services import NGServiceController
-
-from magma.pipelined.rule_mappers import RuleIDToNumMapper, \
- SessionRuleToVersionMapper
+from magma.pipelined.app.vlan_learn import VlanLearnController
+from magma.pipelined.app.xwf_passthru import XWFPassthruController
+from magma.pipelined.internal_ip_allocator import InternalIPAllocator
from magma.pipelined.ipv6_prefix_store import InterfaceIDToPrefixMapper
+from magma.pipelined.rule_mappers import (
+ RuleIDToNumMapper,
+ SessionRuleToVersionMapper,
+)
from magma.pipelined.tunnel_id_store import TunnelToTunnelMapper
-from magma.pipelined.internal_ip_allocator import InternalIPAllocator
from ryu.base.app_manager import AppManager
-from magma.common.service import MagmaService
-from magma.common.service_registry import ServiceRegistry
-from magma.configuration import environment
-from magma.pipelined.app.classifier import Classifier
-from magma.pipelined.app.he import HeaderEnrichmentController, PROXY_TABLE
-
# Type is either Physical or Logical, highest order_priority is at zero
App = namedtuple('App', ['name', 'module', 'type', 'order_priority'])
@@ -533,7 +537,6 @@ def load(self):
logging.warning("Pipelined waiting for redis...")
time.sleep(1)
self.rule_id_mapper.setup_redis()
- self.session_rule_version_mapper.setup_redis()
self.interface_to_prefix_mapper.setup_redis()
self.tunnel_id_mapper.setup_redis()
diff --git a/lte/gateway/python/magma/pipelined/set_interface_client.py b/lte/gateway/python/magma/pipelined/set_interface_client.py
index 18271bd55108..26893d598368 100644
--- a/lte/gateway/python/magma/pipelined/set_interface_client.py
+++ b/lte/gateway/python/magma/pipelined/set_interface_client.py
@@ -11,12 +11,10 @@
limitations under the License.
"""
-import grpc
import logging
-from lte.protos.session_manager_pb2 import (
- UPFNodeState,
- UPFSessionConfigState)
+import grpc
+from lte.protos.session_manager_pb2 import UPFNodeState, UPFSessionConfigState
from lte.protos.session_manager_pb2_grpc import SetInterfaceForUserPlaneStub
DEFAULT_GRPC_TIMEOUT = 5
diff --git a/lte/gateway/python/magma/pipelined/tests/app/flow_query.py b/lte/gateway/python/magma/pipelined/tests/app/flow_query.py
index 25905d5f85f0..b80a1e4e5133 100644
--- a/lte/gateway/python/magma/pipelined/tests/app/flow_query.py
+++ b/lte/gateway/python/magma/pipelined/tests/app/flow_query.py
@@ -17,7 +17,6 @@
from integ_tests.s1aptests.ovs import LOCALHOST
from integ_tests.s1aptests.ovs.rest_api import get_datapath, get_flows
-
from ryu.lib import hub
FlowStats = namedtuple('FlowData', ['packets', 'bytes', 'duration_sec',
diff --git a/lte/gateway/python/magma/pipelined/tests/app/ng_set_session_msg.py b/lte/gateway/python/magma/pipelined/tests/app/ng_set_session_msg.py
index 78f3d691e45c..29e612e12696 100644
--- a/lte/gateway/python/magma/pipelined/tests/app/ng_set_session_msg.py
+++ b/lte/gateway/python/magma/pipelined/tests/app/ng_set_session_msg.py
@@ -13,27 +13,27 @@
from collections import namedtuple
-from magma.subscriberdb.sid import SIDUtils
-from magma.pipelined.policy_converters import convert_ipv4_str_to_ip_proto
-from lte.protos.policydb_pb2 import FlowMatch, FlowDescription, PolicyRule
-from lte.protos.session_manager_pb2 import NodeID
from lte.protos.pipelined_pb2 import (
- SessionSet,
- SetGroupFAR,
- FwdParam,
- Action,
- OuterHeaderCreation,
- SetGroupPDR,
PDI,
- Fsm_state,
- PdrState,
+ Action,
ActivateFlowsRequest,
DeactivateFlowsRequest,
- RuleModResult,
+ Fsm_state,
+ FwdParam,
+ OuterHeaderCreation,
+ PdrState,
RequestOriginType,
+ RuleModResult,
+ SessionSet,
+ SetGroupFAR,
+ SetGroupPDR,
)
-
+from lte.protos.policydb_pb2 import FlowDescription, FlowMatch, PolicyRule
+from lte.protos.session_manager_pb2 import NodeID
from magma.pipelined.ng_manager.session_state_manager_util import FARRuleEntry
+from magma.pipelined.policy_converters import convert_ipv4_str_to_ip_proto
+from magma.subscriberdb.sid import SIDUtils
+
QoSEnforceRuleEntry = namedtuple(
'QoSEnforceRuleEntry',
['imsi', 'rule_id', 'ipv4_dst', 'allow', 'priority', 'hard_timeout', 'direction'])
diff --git a/lte/gateway/python/magma/pipelined/tests/app/packet_builder.py b/lte/gateway/python/magma/pipelined/tests/app/packet_builder.py
index 4adfaa18a19c..eebe0296980a 100644
--- a/lte/gateway/python/magma/pipelined/tests/app/packet_builder.py
+++ b/lte/gateway/python/magma/pipelined/tests/app/packet_builder.py
@@ -13,10 +13,21 @@
import abc
import logging
-logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
-from scapy.all import Ether, IP, IPv6, ARP, TCP, UDP, ICMP, DHCP, BOOTP, \
- wrpcap, rdpcap
+logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
+from scapy.all import (
+ ARP,
+ BOOTP,
+ DHCP,
+ ICMP,
+ IP,
+ TCP,
+ UDP,
+ Ether,
+ IPv6,
+ rdpcap,
+ wrpcap,
+)
'''
diff --git a/lte/gateway/python/magma/pipelined/tests/app/packet_injector.py b/lte/gateway/python/magma/pipelined/tests/app/packet_injector.py
index 77786b76c732..0795843986da 100644
--- a/lte/gateway/python/magma/pipelined/tests/app/packet_injector.py
+++ b/lte/gateway/python/magma/pipelined/tests/app/packet_injector.py
@@ -13,8 +13,9 @@
import abc
import logging
+
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
-from scapy.all import sendp, srp, wrpcap, rdpcap
+from scapy.all import rdpcap, sendp, srp, wrpcap
class PacketInjector(metaclass=abc.ABCMeta):
diff --git a/lte/gateway/python/magma/pipelined/tests/app/start_pipelined.py b/lte/gateway/python/magma/pipelined/tests/app/start_pipelined.py
index abb8211a2434..567866f018e8 100644
--- a/lte/gateway/python/magma/pipelined/tests/app/start_pipelined.py
+++ b/lte/gateway/python/magma/pipelined/tests/app/start_pipelined.py
@@ -12,18 +12,19 @@
"""
import logging
-import threading
import subprocess
-from enum import Enum
+import threading
from collections import namedtuple
from concurrent.futures import Future
+from enum import Enum
-from magma.pipelined.rule_mappers import RuleIDToNumMapper
+from magma.pipelined.app.base import ControllerType, MagmaController
from magma.pipelined.internal_ip_allocator import InternalIPAllocator
-from magma.pipelined.app.base import MagmaController, ControllerType
-from magma.pipelined.tests.app.exceptions import ServiceRunningError,\
- BadConfigError
-
+from magma.pipelined.rule_mappers import RuleIDToNumMapper
+from magma.pipelined.tests.app.exceptions import (
+ BadConfigError,
+ ServiceRunningError,
+)
from ryu.base.app_manager import AppManager
from ryu.lib import hub
diff --git a/lte/gateway/python/magma/pipelined/tests/app/subscriber.py b/lte/gateway/python/magma/pipelined/tests/app/subscriber.py
index 88c517d1ce53..b58fffb34e95 100644
--- a/lte/gateway/python/magma/pipelined/tests/app/subscriber.py
+++ b/lte/gateway/python/magma/pipelined/tests/app/subscriber.py
@@ -11,18 +11,19 @@
limitations under the License.
"""
+import abc
import logging
import time
from collections import namedtuple
-import abc
import grpc
-from lte.protos.pipelined_pb2 import ActivateFlowsRequest, \
- DeactivateFlowsRequest
-from ryu.lib import hub
-
-from magma.subscriberdb.sid import SIDUtils
+from lte.protos.pipelined_pb2 import (
+ ActivateFlowsRequest,
+ DeactivateFlowsRequest,
+)
from magma.pipelined.policy_converters import convert_ip_str_to_ip_proto
+from magma.subscriberdb.sid import SIDUtils
+from ryu.lib import hub
SubContextConfig = namedtuple('ContextConfig', ['imsi', 'ip', 'ambr',
'table_id'])
@@ -55,7 +56,7 @@ class SubscriberContext(abc.ABC):
"""
@abc.abstractmethod
- def add_dynamic_rule(self, policy_rule):
+ def add_policy(self, policy):
"""
Adds new dynamic rule to subcriber
Args:
@@ -104,18 +105,18 @@ class RyuRPCSubscriberContext(SubscriberContext):
def __init__(self, imsi, ip, pipelined_stub, table_id=5):
self.cfg = SubContextConfig(imsi, ip, default_ambr_config, table_id)
- self._dynamic_rules = []
+ self._policies = []
self._pipelined_stub = pipelined_stub
- def add_dynamic_rule(self, policy_rule):
- self._dynamic_rules.append(policy_rule)
+ def add_policy(self, policy):
+ self._policies.append(policy)
return self
def _activate_subscriber_rules(self):
try_grpc_call_with_retries(
lambda: self._pipelined_stub.ActivateFlows(
ActivateFlowsRequest(sid=SIDUtils.to_pb(self.cfg.imsi),
- dynamic_rules=self._dynamic_rules))
+ policies=self._policies))
)
def _deactivate_subscriber_rules(self):
@@ -134,13 +135,13 @@ class RyuDirectSubscriberContext(SubscriberContext):
def __init__(self, imsi, ip, enforcement_controller, table_id=5,
enforcement_stats_controller=None, nuke_flows_on_exit=True):
self.cfg = SubContextConfig(imsi, ip, default_ambr_config, table_id)
- self._dynamic_rules = []
+ self._policies = []
self._ec = enforcement_controller
self._esc = enforcement_stats_controller
self._nuke_flows_on_exit = nuke_flows_on_exit
- def add_dynamic_rule(self, policy_rule):
- self._dynamic_rules.append(policy_rule)
+ def add_policy(self, policy):
+ self._policies.append(policy)
return self
def _activate_subscriber_rules(self):
@@ -152,7 +153,7 @@ def activate_flows():
uplink_tunnel=None,
ip_addr=ip_addr,
apn_ambr=default_ambr_config,
- dynamic_rules=self._dynamic_rules)
+ policies=self._policies)
if self._esc:
self._esc.activate_rules(
imsi=self.cfg.imsi,
@@ -160,7 +161,7 @@ def activate_flows():
uplink_tunnel=None,
ip_addr=ip_addr,
apn_ambr=default_ambr_config,
- dynamic_rules=self._dynamic_rules)
+ policies=self._policies)
hub.joinall([hub.spawn(activate_flows)])
def _deactivate_subscriber_rules(self):
diff --git a/lte/gateway/python/magma/pipelined/tests/app/table_isolation.py b/lte/gateway/python/magma/pipelined/tests/app/table_isolation.py
index 5d789abae85b..e098459967c1 100644
--- a/lte/gateway/python/magma/pipelined/tests/app/table_isolation.py
+++ b/lte/gateway/python/magma/pipelined/tests/app/table_isolation.py
@@ -14,18 +14,23 @@
import abc
import copy
+from integ_tests.s1aptests.ovs import LOCALHOST
+from integ_tests.s1aptests.ovs.rest_api import (
+ add_flowentry,
+ delete_flowentry,
+ get_datapath,
+)
from lte.protos.mobilityd_pb2 import IPAddress
from magma.pipelined.imsi import encode_imsi
-from magma.pipelined.policy_converters import convert_ip_str_to_ip_proto
from magma.pipelined.openflow.magma_match import MagmaMatch
-from magma.pipelined.openflow.registers import DIRECTION_REG, Direction, \
- IMSI_REG
-from integ_tests.s1aptests.ovs import LOCALHOST
-from integ_tests.s1aptests.ovs.rest_api import get_datapath,\
- delete_flowentry, add_flowentry
-
-from ryu.lib.packet import ether_types
+from magma.pipelined.openflow.registers import (
+ DIRECTION_REG,
+ IMSI_REG,
+ Direction,
+)
+from magma.pipelined.policy_converters import convert_ip_str_to_ip_proto
from ryu.lib import hub
+from ryu.lib.packet import ether_types
class TableIsolator(abc.ABC):
diff --git a/lte/gateway/python/magma/pipelined/tests/ng_node_rpc_servicer.py b/lte/gateway/python/magma/pipelined/tests/ng_node_rpc_servicer.py
index a7fd7adcdd49..aa66f634ae04 100644
--- a/lte/gateway/python/magma/pipelined/tests/ng_node_rpc_servicer.py
+++ b/lte/gateway/python/magma/pipelined/tests/ng_node_rpc_servicer.py
@@ -11,36 +11,38 @@
limitations under the License.
"""
-import warnings
-from typing import List
import subprocess
+import threading
import unittest
-from unittest import TestCase
import unittest.mock
-from unittest.mock import MagicMock
-import grpc
+import warnings
from concurrent import futures
+from typing import List
+from unittest import TestCase
+from unittest.mock import MagicMock
+import grpc
+from lte.protos import session_manager_pb2_grpc
+from lte.protos.session_manager_pb2 import UPFNodeState
+from lte.protos.session_manager_pb2_grpc import SetInterfaceForUserPlaneStub
from magma.pipelined.bridge_util import BridgeTools
+from magma.pipelined.ng_manager.node_state_manager import NodeStateManager
+from magma.pipelined.set_interface_client import (
+ send_node_state_association_request,
+)
from magma.pipelined.tests.app.start_pipelined import (
+ PipelinedController,
TestSetup,
- PipelinedController)
-
+)
from magma.pipelined.tests.pipelined_test_util import (
+ create_service_manager,
start_ryu_app_thread,
stop_ryu_app_thread,
- create_service_manager,
- wait_after_send)
-
-import threading
-
-from lte.protos import session_manager_pb2_grpc
-from lte.protos.session_manager_pb2_grpc import SetInterfaceForUserPlaneStub
-from lte.protos.session_manager_pb2 import UPFNodeState
-from magma.pipelined.ng_manager.node_state_manager import NodeStateManager
-from magma.pipelined.set_interface_client import send_node_state_association_request
-from ryu.lib import hub
+ wait_after_send,
+)
from orc8r.protos.common_pb2 import Void
+from ryu.lib import hub
+
class SMFAssociationServerTest(session_manager_pb2_grpc.SetInterfaceForUserPlaneServicer):
diff --git a/lte/gateway/python/magma/pipelined/tests/old_tests/test_controller.py b/lte/gateway/python/magma/pipelined/tests/old_tests/test_controller.py
index da2552f6c944..58bc171e415f 100644
--- a/lte/gateway/python/magma/pipelined/tests/old_tests/test_controller.py
+++ b/lte/gateway/python/magma/pipelined/tests/old_tests/test_controller.py
@@ -11,22 +11,19 @@
limitations under the License.
"""
-from netaddr import IPNetwork
+import threading
+import time
import unittest
from unittest.mock import MagicMock
-import time
-import threading
+from magma.pipelined.app.base import ControllerType, MagmaController
+from magma.pipelined.openflow.exceptions import MagmaOFError
+from magma.pkt_tester.tests.test_topology_builder import check_env
+from netaddr import IPNetwork
from nose.plugins.skip import SkipTest
from ryu.app.ofctl.exception import InvalidDatapath
from ryu.base.app_manager import AppManager
-from magma.pipelined.openflow.exceptions import MagmaOFError
-from magma.pkt_tester.tests.test_topology_builder import check_env
-from magma.pipelined.app.base import MagmaController, ControllerType
-
-
-
"""
Writing tests for pipelined
=============================
@@ -190,8 +187,8 @@ def setUp(self):
def _generate_topology(self):
# import here, after we've checked the environment
- from ovstest import util
from magma.pkt_tester.topology_builder import TopologyBuilder
+ from ovstest import util
self._topo_builder = TopologyBuilder()
@@ -209,8 +206,8 @@ def _generate_topology(self):
def test_delete_all_flows(self):
# import here, after we've checked the environment
- from ovstest import util
from magma.pkt_tester.topology_builder import OvsException
+ from ovstest import util
# basic setup
self._generate_topology()
@@ -242,8 +239,8 @@ def test_delete_all_flows(self):
def test_delete_table_flows(self):
# import here, after we've checked the environment
- from ovstest import util
from magma.pkt_tester.topology_builder import OvsException
+ from ovstest import util
# basic setup
self._generate_topology()
diff --git a/lte/gateway/python/magma/pipelined/tests/old_tests/test_inout.py b/lte/gateway/python/magma/pipelined/tests/old_tests/test_inout.py
index 8afb41fe91d6..d9ab8a0d0926 100644
--- a/lte/gateway/python/magma/pipelined/tests/old_tests/test_inout.py
+++ b/lte/gateway/python/magma/pipelined/tests/old_tests/test_inout.py
@@ -10,9 +10,10 @@
See the License for the specific language governing permissions and
limitations under the License.
"""
-from test_controller import BaseMagmaTest
import unittest
+from test_controller import BaseMagmaTest
+
@unittest.skip("temporarily disabled")
class InoutTest(BaseMagmaTest.MagmaControllerTest):
@@ -22,8 +23,8 @@ def setUp(self):
def _generate_topology(self):
# import here, after we've checked the environment
- from ovstest import util
from magma.pkt_tester.topology_builder import TopologyBuilder
+ from ovstest import util
self._topo_builder = TopologyBuilder()
@@ -40,8 +41,8 @@ def _generate_topology(self):
self.assertFalse(self._topo_builder.invalid_devices())
def test_add_inout_flows(self):
- from ovstest import util
from magma.pkt_tester.topology_builder import OvsException
+ from ovstest import util
self._generate_topology()
self.controller_thread.start()
diff --git a/lte/gateway/python/magma/pipelined/tests/pipelined_test_util.py b/lte/gateway/python/magma/pipelined/tests/pipelined_test_util.py
index 942b2a517890..dba901f333d6 100644
--- a/lte/gateway/python/magma/pipelined/tests/pipelined_test_util.py
+++ b/lte/gateway/python/magma/pipelined/tests/pipelined_test_util.py
@@ -15,30 +15,33 @@
import os
import re
import subprocess
-import netifaces
-import fakeredis
-
from collections import namedtuple
from concurrent.futures import Future
from difflib import unified_diff
from typing import Dict, List, Optional
-
-from unittest import TestCase
-from unittest import mock
+from unittest import TestCase, mock
from unittest.mock import MagicMock
-from ryu.lib import hub
+import fakeredis
+import netifaces
from lte.protos.mconfig.mconfigs_pb2 import PipelineD
-from lte.protos.pipelined_pb2 import SetupFlowsResult, SetupPolicyRequest, \
- UpdateSubscriberQuotaStateRequest, SetupUEMacRequest
+from lte.protos.pipelined_pb2 import (
+ SetupFlowsResult,
+ SetupPolicyRequest,
+ SetupUEMacRequest,
+ UpdateSubscriberQuotaStateRequest,
+)
+from magma.pipelined.app.base import global_epoch
from magma.pipelined.bridge_util import BridgeTools
+from magma.pipelined.openflow import flows
from magma.pipelined.service_manager import ServiceManager
-from magma.pipelined.tests.app.exceptions import BadConfigError, \
- ServiceRunningError
+from magma.pipelined.tests.app.exceptions import (
+ BadConfigError,
+ ServiceRunningError,
+)
from magma.pipelined.tests.app.flow_query import RyuDirectFlowQuery
from magma.pipelined.tests.app.start_pipelined import StartThread
-from magma.pipelined.app.base import global_epoch
-from magma.pipelined.openflow import flows
+from ryu.lib import hub
"""
Pipelined test util functions can be used for testing pipelined, the usage of
diff --git a/lte/gateway/python/magma/pipelined/tests/snapshots/test_enforcement.EnforcementTableTest.test_subscriber_ipv6_policy.snapshot b/lte/gateway/python/magma/pipelined/tests/snapshots/test_enforcement.EnforcementTableTest.test_subscriber_ipv6_policy.snapshot
index 1b23d9d968e5..53eac34b8e9e 100644
--- a/lte/gateway/python/magma/pipelined/tests/snapshots/test_enforcement.EnforcementTableTest.test_subscriber_ipv6_policy.snapshot
+++ b/lte/gateway/python/magma/pipelined/tests/snapshots/test_enforcement.EnforcementTableTest.test_subscriber_ipv6_policy.snapshot
@@ -2,5 +2,5 @@
cookie=0x0, table=mme(main_table), n_packets=0, n_bytes=0, priority=65535,ipv6,ipv6_dst=de34:431d:1bc:: actions=load:0x48c2739fd9c3->OXM_OF_METADATA[],load:0x10->NXM_NX_REG1[],resubmit(,enforcement(main_table))
cookie=0x0, table=proxy(main_table), n_packets=0, n_bytes=0, priority=1,in_port=16 actions=drop
cookie=0x0, table=proxy(main_table), n_packets=0, n_bytes=0, priority=0 actions=resubmit(,middle(main_table)),set_field:0->reg0,set_field:0->reg3
- cookie=0x2, table=enforcement(main_table), n_packets=1, n_bytes=54, priority=65533,ipv6,reg1=0x1,metadata=0x48c2739fd9c3,ipv6_src=de34:431d:1bc::,ipv6_dst=f333:432::dbca actions=note:b'simple_match',set_field:0x2->reg2,set_field:0->reg4,resubmit(,enforcement_stats(main_table)),resubmit(,egress(main_table))
+ cookie=0x2, table=enforcement(main_table), n_packets=1, n_bytes=54, priority=65533,ipv6,reg1=0x1,metadata=0x48c2739fd9c3,ipv6_src=de34:431d:1bc::,ipv6_dst=f333:432::dbca actions=note:b'simple_match',set_field:0x2->reg2,set_field:0x1->reg4,resubmit(,enforcement_stats(main_table)),resubmit(,egress(main_table))
cookie=0xfffffffffffffffe, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=0 actions=resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
\ No newline at end of file
diff --git a/lte/gateway/python/magma/pipelined/tests/snapshots/test_enforcement.EnforcementTableTest.test_subscriber_policy.snapshot b/lte/gateway/python/magma/pipelined/tests/snapshots/test_enforcement.EnforcementTableTest.test_subscriber_policy.snapshot
index 94c8bb3642b4..ed1494ce9fab 100644
--- a/lte/gateway/python/magma/pipelined/tests/snapshots/test_enforcement.EnforcementTableTest.test_subscriber_policy.snapshot
+++ b/lte/gateway/python/magma/pipelined/tests/snapshots/test_enforcement.EnforcementTableTest.test_subscriber_policy.snapshot
@@ -2,5 +2,5 @@
cookie=0x0, table=mme(main_table), n_packets=0, n_bytes=0, priority=65535,ip,nw_dst=192.168.128.74 actions=load:0x48c2739fd9c3->OXM_OF_METADATA[],load:0x10->NXM_NX_REG1[],resubmit(,enforcement(main_table))
cookie=0x0, table=proxy(main_table), n_packets=0, n_bytes=0, priority=1,in_port=16 actions=drop
cookie=0x0, table=proxy(main_table), n_packets=0, n_bytes=0, priority=0 actions=resubmit(,middle(main_table)),set_field:0->reg0,set_field:0->reg3
- cookie=0x2, table=enforcement(main_table), n_packets=256, n_bytes=8704, priority=65533,ip,reg1=0x1,metadata=0x48c2739fd9c3,nw_src=192.168.128.74,nw_dst=45.10.0.0/24 actions=note:b'simple_match',set_field:0x2->reg2,set_field:0->reg4,resubmit(,enforcement_stats(main_table)),resubmit(,egress(main_table))
+ cookie=0x2, table=enforcement(main_table), n_packets=256, n_bytes=8704, priority=65533,ip,reg1=0x1,metadata=0x48c2739fd9c3,nw_src=192.168.128.74,nw_dst=45.10.0.0/24 actions=note:b'simple_match',set_field:0x2->reg2,set_field:0x1->reg4,resubmit(,enforcement_stats(main_table)),resubmit(,egress(main_table))
cookie=0xfffffffffffffffe, table=enforcement(main_table), n_packets=3840, n_bytes=130560, priority=0 actions=resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
\ No newline at end of file
diff --git a/lte/gateway/python/magma/pipelined/tests/snapshots/test_enforcement.EnforcementTableTest.test_subscriber_two_policies.snapshot b/lte/gateway/python/magma/pipelined/tests/snapshots/test_enforcement.EnforcementTableTest.test_subscriber_two_policies.snapshot
index c112914c5c89..b40ee1377e4e 100644
--- a/lte/gateway/python/magma/pipelined/tests/snapshots/test_enforcement.EnforcementTableTest.test_subscriber_two_policies.snapshot
+++ b/lte/gateway/python/magma/pipelined/tests/snapshots/test_enforcement.EnforcementTableTest.test_subscriber_two_policies.snapshot
@@ -3,5 +3,5 @@
cookie=0x0, table=proxy(main_table), n_packets=0, n_bytes=0, priority=1,in_port=16 actions=drop
cookie=0x0, table=proxy(main_table), n_packets=0, n_bytes=0, priority=0 actions=resubmit(,middle(main_table)),set_field:0->reg0,set_field:0->reg3
cookie=0x3, table=enforcement(main_table), n_packets=42, n_bytes=1428, priority=65533,ip,reg1=0x10,metadata=0x5f04fb434e009,nw_src=15.0.0.0/24,nw_dst=192.168.128.74 actions=note:b'match',set_field:0x2->reg3,resubmit(,enforcement_stats(main_table))
- cookie=0x4, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65533,tcp,reg1=0x1,metadata=0x5f04fb434e009,nw_src=192.168.128.74 actions=note:b'no_match',set_field:0x4->reg2,set_field:0->reg4,resubmit(,enforcement_stats(main_table)),resubmit(,egress(main_table))
+ cookie=0x4, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65533,tcp,reg1=0x1,metadata=0x5f04fb434e009,nw_src=192.168.128.74 actions=note:b'no_match',set_field:0x4->reg2,set_field:0x1->reg4,resubmit(,enforcement_stats(main_table)),resubmit(,egress(main_table))
cookie=0xfffffffffffffffe, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=0 actions=resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
\ No newline at end of file
diff --git a/lte/gateway/python/magma/pipelined/tests/snapshots/test_gy.GYTableTest.test_subscriber_redirect_policy.snapshot b/lte/gateway/python/magma/pipelined/tests/snapshots/test_gy.GYTableTest.test_subscriber_redirect_policy.snapshot
index f8815f55eec6..cd1c883140b8 100644
--- a/lte/gateway/python/magma/pipelined/tests/snapshots/test_gy.GYTableTest.test_subscriber_redirect_policy.snapshot
+++ b/lte/gateway/python/magma/pipelined/tests/snapshots/test_gy.GYTableTest.test_subscriber_redirect_policy.snapshot
@@ -4,18 +4,18 @@
cookie=0x1, table=gy(main_table), priority=13,tcp,reg1=0x1,metadata=0x48c2739fd9c3,vlan_tci=0x1000/0x1000,tp_dst=80 actions=learn(table=204,priority=12,cookie=0x1,eth_type=0x800,nw_proto=6,ip_src=192.168.128.1,ip_dst=192.168.0.1,NXM_OF_TCP_DST[]=NXM_OF_TCP_SRC[],tcp_src=8080,load:NXM_OF_ETH_SRC[]->NXM_OF_ETH_DST[],load:0x48c2739fd9c3->OXM_OF_METADATA[],load:NXM_OF_IP_SRC[]->NXM_OF_IP_DST[],load:NXM_OF_IP_DST[]->NXM_OF_IP_SRC[],load:NXM_OF_TCP_DST[]->NXM_OF_TCP_SRC[]),mod_nw_src:192.168.0.1,mod_nw_dst:192.168.128.1,mod_dl_dst:00:11:22:33:44:55,mod_tp_dst:8080,strip_vlan,LOCAL
cookie=0x1, table=gy(main_table), priority=13,tcp,reg1=0x1,metadata=0x48c2739fd9c3,vlan_tci=0x1000/0x1000,tp_dst=8080 actions=learn(table=204,priority=12,cookie=0x1,eth_type=0x800,nw_proto=6,ip_src=192.168.128.1,ip_dst=192.168.0.1,NXM_OF_TCP_DST[]=NXM_OF_TCP_SRC[],tcp_src=8080,load:NXM_OF_ETH_SRC[]->NXM_OF_ETH_DST[],load:0x48c2739fd9c3->OXM_OF_METADATA[],load:NXM_OF_IP_SRC[]->NXM_OF_IP_DST[],load:NXM_OF_IP_DST[]->NXM_OF_IP_SRC[],load:NXM_OF_TCP_DST[]->NXM_OF_TCP_SRC[]),mod_nw_src:192.168.0.1,mod_nw_dst:192.168.128.1,mod_dl_dst:00:11:22:33:44:55,mod_tp_dst:8080,strip_vlan,LOCAL
cookie=0x1, table=gy(main_table), priority=13,tcp,reg1=0x1,metadata=0x48c2739fd9c3,vlan_tci=0x1000/0x1000,tp_dst=8008 actions=learn(table=204,priority=12,cookie=0x1,eth_type=0x800,nw_proto=6,ip_src=192.168.128.1,ip_dst=192.168.0.1,NXM_OF_TCP_DST[]=NXM_OF_TCP_SRC[],tcp_src=8080,load:NXM_OF_ETH_SRC[]->NXM_OF_ETH_DST[],load:0x48c2739fd9c3->OXM_OF_METADATA[],load:NXM_OF_IP_SRC[]->NXM_OF_IP_DST[],load:NXM_OF_IP_DST[]->NXM_OF_IP_SRC[],load:NXM_OF_TCP_DST[]->NXM_OF_TCP_SRC[]),mod_nw_src:192.168.0.1,mod_nw_dst:192.168.128.1,mod_dl_dst:00:11:22:33:44:55,mod_tp_dst:8080,strip_vlan,LOCAL
- cookie=0x1, table=gy(main_table), priority=3,udp,reg1=0x1,metadata=0x48c2739fd9c3,tp_dst=53 actions=note:b'redir_test',set_field:0x1->reg2,set_field:0->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
- cookie=0x1, table=gy(main_table), priority=3,tcp,reg1=0x1,metadata=0x48c2739fd9c3,tp_dst=53 actions=note:b'redir_test',set_field:0x1->reg2,set_field:0->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
+ cookie=0x1, table=gy(main_table), priority=3,udp,reg1=0x1,metadata=0x48c2739fd9c3,tp_dst=53 actions=note:b'redir_test',set_field:0x1->reg2,set_field:0x1->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
+ cookie=0x1, table=gy(main_table), priority=3,tcp,reg1=0x1,metadata=0x48c2739fd9c3,tp_dst=53 actions=note:b'redir_test',set_field:0x1->reg2,set_field:0x1->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
cookie=0x1, table=gy(main_table), priority=12,tcp,reg1=0x1,metadata=0x48c2739fd9c3,tp_dst=80 actions=learn(table=204,priority=12,cookie=0x1,eth_type=0x800,nw_proto=6,ip_src=192.168.128.1,ip_dst=192.168.0.1,NXM_OF_TCP_DST[]=NXM_OF_TCP_SRC[],tcp_src=8080,load:NXM_OF_ETH_SRC[]->NXM_OF_ETH_DST[],load:0x48c2739fd9c3->OXM_OF_METADATA[],load:NXM_OF_IP_SRC[]->NXM_OF_IP_DST[],load:NXM_OF_IP_DST[]->NXM_OF_IP_SRC[],load:NXM_OF_TCP_DST[]->NXM_OF_TCP_SRC[]),mod_nw_src:192.168.0.1,mod_nw_dst:192.168.128.1,mod_dl_dst:00:11:22:33:44:55,mod_tp_dst:8080,LOCAL
cookie=0x1, table=gy(main_table), priority=12,tcp,reg1=0x1,metadata=0x48c2739fd9c3,tp_dst=8080 actions=learn(table=204,priority=12,cookie=0x1,eth_type=0x800,nw_proto=6,ip_src=192.168.128.1,ip_dst=192.168.0.1,NXM_OF_TCP_DST[]=NXM_OF_TCP_SRC[],tcp_src=8080,load:NXM_OF_ETH_SRC[]->NXM_OF_ETH_DST[],load:0x48c2739fd9c3->OXM_OF_METADATA[],load:NXM_OF_IP_SRC[]->NXM_OF_IP_DST[],load:NXM_OF_IP_DST[]->NXM_OF_IP_SRC[],load:NXM_OF_TCP_DST[]->NXM_OF_TCP_SRC[]),mod_nw_src:192.168.0.1,mod_nw_dst:192.168.128.1,mod_dl_dst:00:11:22:33:44:55,mod_tp_dst:8080,LOCAL
cookie=0x1, table=gy(main_table), priority=12,tcp,reg1=0x1,metadata=0x48c2739fd9c3,tp_dst=8008 actions=learn(table=204,priority=12,cookie=0x1,eth_type=0x800,nw_proto=6,ip_src=192.168.128.1,ip_dst=192.168.0.1,NXM_OF_TCP_DST[]=NXM_OF_TCP_SRC[],tcp_src=8080,load:NXM_OF_ETH_SRC[]->NXM_OF_ETH_DST[],load:0x48c2739fd9c3->OXM_OF_METADATA[],load:NXM_OF_IP_SRC[]->NXM_OF_IP_DST[],load:NXM_OF_IP_DST[]->NXM_OF_IP_SRC[],load:NXM_OF_TCP_DST[]->NXM_OF_TCP_SRC[]),mod_nw_src:192.168.0.1,mod_nw_dst:192.168.128.1,mod_dl_dst:00:11:22:33:44:55,mod_tp_dst:8080,LOCAL
cookie=0x1, table=gy(main_table), priority=10,tcp,reg1=0x10,metadata=0x48c2739fd9c3,in_port=LOCAL actions=resubmit(,egress(main_table)),set_field:0->reg0,set_field:0->reg3
- cookie=0x1, table=gy(main_table), priority=4,ip,reg1=0x1,metadata=0x48c2739fd9c3,nw_dst=185.128.101.5 actions=note:b'redir_test',set_field:0x1->reg2,set_field:0->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
- cookie=0x1, table=gy(main_table), priority=4,ip,reg1=0x1,metadata=0x48c2739fd9c3,nw_dst=185.128.121.4 actions=note:b'redir_test',set_field:0x1->reg2,set_field:0->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
- cookie=0x1, table=gy(main_table), priority=4,ip,reg1=0x10,metadata=0x48c2739fd9c3,nw_src=185.128.101.5 actions=note:b'redir_test',set_field:0x1->reg2,set_field:0->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
- cookie=0x1, table=gy(main_table), priority=4,ip,reg1=0x10,metadata=0x48c2739fd9c3,nw_src=185.128.121.4 actions=note:b'redir_test',set_field:0x1->reg2,set_field:0->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
- cookie=0x1, table=gy(main_table), priority=3,udp,reg1=0x10,metadata=0x48c2739fd9c3,tp_src=53 actions=note:b'redir_test',set_field:0x1->reg2,set_field:0->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
- cookie=0x1, table=gy(main_table), priority=3,tcp,reg1=0x10,metadata=0x48c2739fd9c3,tp_src=53 actions=note:b'redir_test',set_field:0x1->reg2,set_field:0->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
+ cookie=0x1, table=gy(main_table), priority=4,ip,reg1=0x1,metadata=0x48c2739fd9c3,nw_dst=185.128.101.5 actions=note:b'redir_test',set_field:0x1->reg2,set_field:0x1->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
+ cookie=0x1, table=gy(main_table), priority=4,ip,reg1=0x1,metadata=0x48c2739fd9c3,nw_dst=185.128.121.4 actions=note:b'redir_test',set_field:0x1->reg2,set_field:0x1->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
+ cookie=0x1, table=gy(main_table), priority=4,ip,reg1=0x10,metadata=0x48c2739fd9c3,nw_src=185.128.101.5 actions=note:b'redir_test',set_field:0x1->reg2,set_field:0x1->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
+ cookie=0x1, table=gy(main_table), priority=4,ip,reg1=0x10,metadata=0x48c2739fd9c3,nw_src=185.128.121.4 actions=note:b'redir_test',set_field:0x1->reg2,set_field:0x1->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
+ cookie=0x1, table=gy(main_table), priority=3,udp,reg1=0x10,metadata=0x48c2739fd9c3,tp_src=53 actions=note:b'redir_test',set_field:0x1->reg2,set_field:0x1->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
+ cookie=0x1, table=gy(main_table), priority=3,tcp,reg1=0x10,metadata=0x48c2739fd9c3,tp_src=53 actions=note:b'redir_test',set_field:0x1->reg2,set_field:0x1->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
cookie=0x1, table=gy(main_table), priority=1,metadata=0x48c2739fd9c3 actions=drop
table=gy(main_table), priority=0 actions=resubmit(,enforcement(main_table)),set_field:0->reg0,set_field:0->reg3
cookie=0x1, table=204, priority=12,tcp,nw_src=192.168.128.1,nw_dst=192.168.0.1,tp_src=8080,tp_dst=42132 actions=load:0x1201020aabb->NXM_OF_ETH_DST[],load:0x48c2739fd9c3->OXM_OF_METADATA[],load:0xc0a8804a->NXM_OF_IP_DST[],load:0x972a297a->NXM_OF_IP_SRC[],load:0x50->NXM_OF_TCP_SRC[]
\ No newline at end of file
diff --git a/lte/gateway/python/magma/pipelined/tests/snapshots/test_gy.GYTableTest.test_subscriber_restrict_policy.snapshot b/lte/gateway/python/magma/pipelined/tests/snapshots/test_gy.GYTableTest.test_subscriber_restrict_policy.snapshot
index b303821d29a0..25ca0293fec0 100644
--- a/lte/gateway/python/magma/pipelined/tests/snapshots/test_gy.GYTableTest.test_subscriber_restrict_policy.snapshot
+++ b/lte/gateway/python/magma/pipelined/tests/snapshots/test_gy.GYTableTest.test_subscriber_restrict_policy.snapshot
@@ -1,6 +1,6 @@
priority=65535,ip,nw_src=192.168.128.74 actions=load:0x48c2739fd9c3->OXM_OF_METADATA[],load:0x1->NXM_NX_REG1[],resubmit(,gy(main_table))
priority=65535,ip,nw_dst=192.168.128.74 actions=load:0x48c2739fd9c3->OXM_OF_METADATA[],load:0x10->NXM_NX_REG1[],resubmit(,gy(main_table))
priority=10,in_port=LOCAL actions=resubmit(,204),resubmit(,ingress(main_table)),set_field:0->reg0,set_field:0->reg3
- cookie=0x2, table=gy(main_table), priority=65533,ip,reg1=0x1,metadata=0x48c2739fd9c3,nw_src=192.168.128.74,nw_dst=8.8.8.0/24 actions=note:b'restrict_match',set_field:0x2->reg2,set_field:0->reg4,resubmit(,enforcement_stats(main_table)),resubmit(,egress(main_table))
+ cookie=0x2, table=gy(main_table), priority=65533,ip,reg1=0x1,metadata=0x48c2739fd9c3,nw_src=192.168.128.74,nw_dst=8.8.8.0/24 actions=note:b'restrict_match',set_field:0x2->reg2,set_field:0x1->reg4,resubmit(,enforcement_stats(main_table)),resubmit(,egress(main_table))
table=gy(main_table), priority=0 actions=resubmit(,enforcement(main_table)),set_field:0->reg0,set_field:0->reg3
cookie=0x1, table=204, priority=12,tcp,nw_src=192.168.128.1,nw_dst=192.168.0.1,tp_src=8080,tp_dst=42132 actions=load:0x1201020aabb->NXM_OF_ETH_DST[],load:0x48c2739fd9c3->OXM_OF_METADATA[],load:0xc0a8804a->NXM_OF_IP_DST[],load:0x972a297a->NXM_OF_IP_SRC[],load:0x50->NXM_OF_TCP_SRC[]
\ No newline at end of file
diff --git a/lte/gateway/python/magma/pipelined/tests/snapshots/test_he.EnforcementTableHeTest.test_subscriber_policy_with_he.snapshot b/lte/gateway/python/magma/pipelined/tests/snapshots/test_he.EnforcementTableHeTest.test_subscriber_policy_with_he.snapshot
index 982e36fd9577..3bf52189b62b 100644
--- a/lte/gateway/python/magma/pipelined/tests/snapshots/test_he.EnforcementTableHeTest.test_subscriber_policy_with_he.snapshot
+++ b/lte/gateway/python/magma/pipelined/tests/snapshots/test_he.EnforcementTableHeTest.test_subscriber_policy_with_he.snapshot
@@ -8,5 +8,5 @@
cookie=0x1, table=proxy(main_table), n_packets=0, n_bytes=0, priority=10,tcp,reg10=0,nw_src=192.168.128.74,nw_dst=45.10.0.0/24,tp_dst=80 actions=set_field:0x1->reg1,set_field:0x1->reg6,set_field:0x1->reg10,resubmit(,middle(main_table))
cookie=0x0, table=proxy(main_table), n_packets=0, n_bytes=0, priority=1,in_port=16 actions=drop
cookie=0x0, table=proxy(main_table), n_packets=0, n_bytes=0, priority=0 actions=resubmit(,middle(main_table)),set_field:0->reg0,set_field:0->reg3
- cookie=0x1, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65533,ip,reg1=0x1,metadata=0x48c2739fd9c3,nw_src=192.168.128.74,nw_dst=45.10.0.0/24 actions=note:b'simple_match',set_field:0x1->reg2,set_field:0->reg4,resubmit(,enforcement_stats(main_table)),resubmit(,egress(main_table))
+ cookie=0x1, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65533,ip,reg1=0x1,metadata=0x48c2739fd9c3,nw_src=192.168.128.74,nw_dst=45.10.0.0/24 actions=note:b'simple_match',set_field:0x1->reg2,set_field:0x1->reg4,resubmit(,enforcement_stats(main_table)),resubmit(,egress(main_table))
cookie=0xfffffffffffffffe, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=0 actions=resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
\ No newline at end of file
diff --git a/lte/gateway/python/magma/pipelined/tests/snapshots/test_redirect.RedirectTest.test_ipv4_redirect.snapshot b/lte/gateway/python/magma/pipelined/tests/snapshots/test_redirect.RedirectTest.test_ipv4_redirect.snapshot
index 6ef198cab2d4..d4c71644ff86 100644
--- a/lte/gateway/python/magma/pipelined/tests/snapshots/test_redirect.RedirectTest.test_ipv4_redirect.snapshot
+++ b/lte/gateway/python/magma/pipelined/tests/snapshots/test_redirect.RedirectTest.test_ipv4_redirect.snapshot
@@ -1,14 +1,14 @@
cookie=0x0, table=mme(main_table), n_packets=1, n_bytes=54, priority=65535,ip,nw_src=192.168.128.74 actions=load:0x574fbdf0d9c3->OXM_OF_METADATA[],load:0x1->NXM_NX_REG1[],resubmit(,enforcement(main_table))
cookie=0x0, table=mme(main_table), n_packets=0, n_bytes=0, priority=65535,ip,nw_dst=192.168.128.74 actions=load:0x574fbdf0d9c3->OXM_OF_METADATA[],load:0x10->NXM_NX_REG1[],resubmit(,enforcement(main_table))
- cookie=0x1, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65533,ip,reg1=0x1,metadata=0x574fbdf0d9c3,nw_src=192.168.128.74,nw_dst=54.12.31.42 actions=note:b'redir_ip_test',set_field:0x1->reg2,set_field:0->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
- cookie=0x1, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65533,ip,reg1=0x10,metadata=0x574fbdf0d9c3,nw_src=54.12.31.42,nw_dst=192.168.128.74 actions=note:b'redir_ip_test',set_field:0x1->reg2,set_field:0->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
- cookie=0x1, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65532,udp,reg1=0x10,metadata=0x574fbdf0d9c3,tp_src=53 actions=note:b'redir_ip_test',set_field:0x1->reg2,set_field:0->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
- cookie=0x1, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65532,tcp,reg1=0x10,metadata=0x574fbdf0d9c3,tp_src=53 actions=note:b'redir_ip_test',set_field:0x1->reg2,set_field:0->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
- cookie=0x1, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65532,udp,reg1=0x1,metadata=0x574fbdf0d9c3,tp_dst=53 actions=note:b'redir_ip_test',set_field:0x1->reg2,set_field:0->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
- cookie=0x1, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65532,tcp,reg1=0x1,metadata=0x574fbdf0d9c3,tp_dst=53 actions=note:b'redir_ip_test',set_field:0x1->reg2,set_field:0->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
+ cookie=0x1, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65533,ip,reg1=0x1,metadata=0x574fbdf0d9c3,nw_src=192.168.128.74,nw_dst=54.12.31.42 actions=note:b'redir_ip_test',set_field:0x1->reg2,set_field:0x1->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
+ cookie=0x1, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65533,ip,reg1=0x10,metadata=0x574fbdf0d9c3,nw_src=54.12.31.42,nw_dst=192.168.128.74 actions=note:b'redir_ip_test',set_field:0x1->reg2,set_field:0x1->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
+ cookie=0x1, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65532,udp,reg1=0x10,metadata=0x574fbdf0d9c3,tp_src=53 actions=note:b'redir_ip_test',set_field:0x1->reg2,set_field:0x1->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
+ cookie=0x1, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65532,tcp,reg1=0x10,metadata=0x574fbdf0d9c3,tp_src=53 actions=note:b'redir_ip_test',set_field:0x1->reg2,set_field:0x1->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
+ cookie=0x1, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65532,udp,reg1=0x1,metadata=0x574fbdf0d9c3,tp_dst=53 actions=note:b'redir_ip_test',set_field:0x1->reg2,set_field:0x1->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
+ cookie=0x1, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65532,tcp,reg1=0x1,metadata=0x574fbdf0d9c3,tp_dst=53 actions=note:b'redir_ip_test',set_field:0x1->reg2,set_field:0x1->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
cookie=0x1, table=enforcement(main_table), n_packets=1, n_bytes=54, priority=65532,ip,reg0=0,reg1=0x1,metadata=0x574fbdf0d9c3,nw_src=192.168.128.74 actions=note:b'redir_ip_test',resubmit(,enforcement(scratch_table_0))
cookie=0x1, table=enforcement(main_table), n_packets=1, n_bytes=54, priority=65532,ip,reg0=0x1,reg1=0x1,metadata=0x574fbdf0d9c3,nw_src=192.168.128.74 actions=note:b'redir_ip_test',resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
cookie=0x1, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65532,tcp,reg1=0x10,metadata=0x574fbdf0d9c3,nw_src=192.168.128.1,nw_dst=192.168.128.74,tp_src=8080,tp_dst=42132 actions=load:0x972a297a->NXM_OF_IP_SRC[],load:0x50->NXM_OF_TCP_SRC[],LOCAL
cookie=0xfffffffffffffffe, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=0 actions=resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
- cookie=0x1, table=enforcement(scratch_table_0), n_packets=1, n_bytes=54, priority=65532,tcp,reg1=0x1,metadata=0x574fbdf0d9c3,tp_dst=80 actions=learn(table=enforcement(main_table),priority=65532,cookie=0x1,eth_type=0x800,nw_proto=6,reg1=0x10,ip_src=192.168.128.1,NXM_OF_IP_DST[]=NXM_OF_IP_SRC[],NXM_OF_TCP_DST[]=NXM_OF_TCP_SRC[],tcp_src=8080,metadata=0x574fbdf0d9c3,load:NXM_OF_IP_DST[]->NXM_OF_IP_SRC[],load:0x50->NXM_OF_TCP_SRC[],output:OXM_OF_IN_PORT[0..15]),set_field:0x1->reg0,mod_nw_dst:192.168.128.1,mod_tp_dst:8080,note:b'redir_ip_test',set_field:0x1->reg2,set_field:0->reg4,resubmit(,enforcement(main_table))
+ cookie=0x1, table=enforcement(scratch_table_0), n_packets=1, n_bytes=54, priority=65532,tcp,reg1=0x1,metadata=0x574fbdf0d9c3,tp_dst=80 actions=learn(table=enforcement(main_table),priority=65532,cookie=0x1,eth_type=0x800,nw_proto=6,reg1=0x10,ip_src=192.168.128.1,NXM_OF_IP_DST[]=NXM_OF_IP_SRC[],NXM_OF_TCP_DST[]=NXM_OF_TCP_SRC[],tcp_src=8080,metadata=0x574fbdf0d9c3,load:NXM_OF_IP_DST[]->NXM_OF_IP_SRC[],load:0x50->NXM_OF_TCP_SRC[],output:OXM_OF_IN_PORT[0..15]),set_field:0x1->reg0,mod_nw_dst:192.168.128.1,mod_tp_dst:8080,note:b'redir_ip_test',set_field:0x1->reg2,set_field:0x1->reg4,resubmit(,enforcement(main_table))
cookie=0x1, table=enforcement(scratch_table_0), n_packets=0, n_bytes=0, priority=1,metadata=0x574fbdf0d9c3 actions=drop
\ No newline at end of file
diff --git a/lte/gateway/python/magma/pipelined/tests/snapshots/test_redirect.RedirectTest.test_url_redirect.snapshot b/lte/gateway/python/magma/pipelined/tests/snapshots/test_redirect.RedirectTest.test_url_redirect.snapshot
index 17084747e472..1c2f348c1e35 100644
--- a/lte/gateway/python/magma/pipelined/tests/snapshots/test_redirect.RedirectTest.test_url_redirect.snapshot
+++ b/lte/gateway/python/magma/pipelined/tests/snapshots/test_redirect.RedirectTest.test_url_redirect.snapshot
@@ -1,16 +1,16 @@
cookie=0x0, table=mme(main_table), n_packets=1, n_bytes=54, priority=65535,ip,nw_src=192.168.128.74 actions=load:0x48c2739fd9c3->OXM_OF_METADATA[],load:0x1->NXM_NX_REG1[],resubmit(,enforcement(main_table))
cookie=0x0, table=mme(main_table), n_packets=0, n_bytes=0, priority=65535,ip,nw_dst=192.168.128.74 actions=load:0x48c2739fd9c3->OXM_OF_METADATA[],load:0x10->NXM_NX_REG1[],resubmit(,enforcement(main_table))
- cookie=0x2, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65533,ip,reg1=0x1,metadata=0x48c2739fd9c3,nw_src=192.168.128.74,nw_dst=185.128.101.5 actions=note:b'redir_test',set_field:0x2->reg2,set_field:0->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
- cookie=0x2, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65533,ip,reg1=0x10,metadata=0x48c2739fd9c3,nw_src=185.128.101.5,nw_dst=192.168.128.74 actions=note:b'redir_test',set_field:0x2->reg2,set_field:0->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
- cookie=0x2, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65533,ip,reg1=0x1,metadata=0x48c2739fd9c3,nw_src=192.168.128.74,nw_dst=185.128.121.4 actions=note:b'redir_test',set_field:0x2->reg2,set_field:0->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
- cookie=0x2, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65533,ip,reg1=0x10,metadata=0x48c2739fd9c3,nw_src=185.128.121.4,nw_dst=192.168.128.74 actions=note:b'redir_test',set_field:0x2->reg2,set_field:0->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
- cookie=0x2, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65532,udp,reg1=0x10,metadata=0x48c2739fd9c3,tp_src=53 actions=note:b'redir_test',set_field:0x2->reg2,set_field:0->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
- cookie=0x2, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65532,tcp,reg1=0x10,metadata=0x48c2739fd9c3,tp_src=53 actions=note:b'redir_test',set_field:0x2->reg2,set_field:0->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
- cookie=0x2, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65532,udp,reg1=0x1,metadata=0x48c2739fd9c3,tp_dst=53 actions=note:b'redir_test',set_field:0x2->reg2,set_field:0->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
- cookie=0x2, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65532,tcp,reg1=0x1,metadata=0x48c2739fd9c3,tp_dst=53 actions=note:b'redir_test',set_field:0x2->reg2,set_field:0->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
+ cookie=0x2, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65533,ip,reg1=0x1,metadata=0x48c2739fd9c3,nw_src=192.168.128.74,nw_dst=185.128.101.5 actions=note:b'redir_test',set_field:0x2->reg2,set_field:0x1->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
+ cookie=0x2, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65533,ip,reg1=0x10,metadata=0x48c2739fd9c3,nw_src=185.128.101.5,nw_dst=192.168.128.74 actions=note:b'redir_test',set_field:0x2->reg2,set_field:0x1->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
+ cookie=0x2, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65533,ip,reg1=0x1,metadata=0x48c2739fd9c3,nw_src=192.168.128.74,nw_dst=185.128.121.4 actions=note:b'redir_test',set_field:0x2->reg2,set_field:0x1->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
+ cookie=0x2, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65533,ip,reg1=0x10,metadata=0x48c2739fd9c3,nw_src=185.128.121.4,nw_dst=192.168.128.74 actions=note:b'redir_test',set_field:0x2->reg2,set_field:0x1->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
+ cookie=0x2, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65532,udp,reg1=0x10,metadata=0x48c2739fd9c3,tp_src=53 actions=note:b'redir_test',set_field:0x2->reg2,set_field:0x1->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
+ cookie=0x2, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65532,tcp,reg1=0x10,metadata=0x48c2739fd9c3,tp_src=53 actions=note:b'redir_test',set_field:0x2->reg2,set_field:0x1->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
+ cookie=0x2, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65532,udp,reg1=0x1,metadata=0x48c2739fd9c3,tp_dst=53 actions=note:b'redir_test',set_field:0x2->reg2,set_field:0x1->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
+ cookie=0x2, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65532,tcp,reg1=0x1,metadata=0x48c2739fd9c3,tp_dst=53 actions=note:b'redir_test',set_field:0x2->reg2,set_field:0x1->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
cookie=0x2, table=enforcement(main_table), n_packets=1, n_bytes=54, priority=65532,ip,reg0=0,reg1=0x1,metadata=0x48c2739fd9c3,nw_src=192.168.128.74 actions=note:b'redir_test',resubmit(,enforcement(scratch_table_0))
cookie=0x2, table=enforcement(main_table), n_packets=1, n_bytes=54, priority=65532,ip,reg0=0x1,reg1=0x1,metadata=0x48c2739fd9c3,nw_src=192.168.128.74 actions=note:b'redir_test',resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
cookie=0x2, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65532,tcp,reg1=0x10,metadata=0x48c2739fd9c3,nw_src=192.168.128.1,nw_dst=192.168.128.74,tp_src=8080,tp_dst=42132 actions=load:0x972a297a->NXM_OF_IP_SRC[],load:0x50->NXM_OF_TCP_SRC[],LOCAL
cookie=0xfffffffffffffffe, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=0 actions=resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
- cookie=0x2, table=enforcement(scratch_table_0), n_packets=1, n_bytes=54, priority=65532,tcp,reg1=0x1,metadata=0x48c2739fd9c3,tp_dst=80 actions=learn(table=enforcement(main_table),priority=65532,cookie=0x2,eth_type=0x800,nw_proto=6,reg1=0x10,ip_src=192.168.128.1,NXM_OF_IP_DST[]=NXM_OF_IP_SRC[],NXM_OF_TCP_DST[]=NXM_OF_TCP_SRC[],tcp_src=8080,metadata=0x48c2739fd9c3,load:NXM_OF_IP_DST[]->NXM_OF_IP_SRC[],load:0x50->NXM_OF_TCP_SRC[],output:OXM_OF_IN_PORT[0..15]),set_field:0x1->reg0,mod_nw_dst:192.168.128.1,mod_tp_dst:8080,note:b'redir_test',set_field:0x2->reg2,set_field:0->reg4,resubmit(,enforcement(main_table))
+ cookie=0x2, table=enforcement(scratch_table_0), n_packets=1, n_bytes=54, priority=65532,tcp,reg1=0x1,metadata=0x48c2739fd9c3,tp_dst=80 actions=learn(table=enforcement(main_table),priority=65532,cookie=0x2,eth_type=0x800,nw_proto=6,reg1=0x10,ip_src=192.168.128.1,NXM_OF_IP_DST[]=NXM_OF_IP_SRC[],NXM_OF_TCP_DST[]=NXM_OF_TCP_SRC[],tcp_src=8080,metadata=0x48c2739fd9c3,load:NXM_OF_IP_DST[]->NXM_OF_IP_SRC[],load:0x50->NXM_OF_TCP_SRC[],output:OXM_OF_IN_PORT[0..15]),set_field:0x1->reg0,mod_nw_dst:192.168.128.1,mod_tp_dst:8080,note:b'redir_test',set_field:0x2->reg2,set_field:0x1->reg4,resubmit(,enforcement(main_table))
cookie=0x2, table=enforcement(scratch_table_0), n_packets=0, n_bytes=0, priority=1,metadata=0x48c2739fd9c3 actions=drop
\ No newline at end of file
diff --git a/lte/gateway/python/magma/pipelined/tests/snapshots/test_restart_resilience.RestartResilienceTest.test_enforcement_ipv6_restart.after_restart.snapshot b/lte/gateway/python/magma/pipelined/tests/snapshots/test_restart_resilience.RestartResilienceTest.test_enforcement_ipv6_restart.after_restart.snapshot
new file mode 100644
index 000000000000..cd1b36bfcfb4
--- /dev/null
+++ b/lte/gateway/python/magma/pipelined/tests/snapshots/test_restart_resilience.RestartResilienceTest.test_enforcement_ipv6_restart.after_restart.snapshot
@@ -0,0 +1,5 @@
+ cookie=0x1, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65533,ipv6,reg1=0x1,metadata=0x48c274b89cc3,ipv6_src=fe80:24c3:d0ff:fef3:9d21:4407:d337:1928,ipv6_dst=fe80:: actions=note:b'ipv6_rule',set_field:0x1->reg2,set_field:0x1->reg4,resubmit(,enforcement_stats(main_table)),resubmit(,egress(main_table))
+ cookie=0xfffffffffffffffe, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=0 actions=resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
+ cookie=0x0, table=enforcement_stats(main_table), n_packets=0, n_bytes=0, priority=1,ipv6,reg1=0x10,reg2=0,reg4=0,metadata=0x48c274b89cc3,ipv6_dst=fe80:24c3:d0ff:fef3:9d21:4407:d337:1928 actions=drop
+ cookie=0x0, table=enforcement_stats(main_table), n_packets=0, n_bytes=0, priority=1,ipv6,reg1=0x1,reg2=0,reg4=0,metadata=0x48c274b89cc3,ipv6_src=fe80:24c3:d0ff:fef3:9d21:4407:d337:1928 actions=drop
+ cookie=0xfffffffffffffffe, table=enforcement_stats(main_table), n_packets=0, n_bytes=0, priority=0 actions=drop
diff --git a/lte/gateway/python/magma/pipelined/tests/snapshots/test_restart_resilience.RestartResilienceTest.test_enforcement_ipv6_restart.default_flows.snapshot b/lte/gateway/python/magma/pipelined/tests/snapshots/test_restart_resilience.RestartResilienceTest.test_enforcement_ipv6_restart.default_flows.snapshot
new file mode 100644
index 000000000000..2b9a784e570c
--- /dev/null
+++ b/lte/gateway/python/magma/pipelined/tests/snapshots/test_restart_resilience.RestartResilienceTest.test_enforcement_ipv6_restart.default_flows.snapshot
@@ -0,0 +1,2 @@
+ cookie=0xfffffffffffffffe, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=0 actions=resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
+ cookie=0xfffffffffffffffe, table=enforcement_stats(main_table), n_packets=0, n_bytes=0, priority=0 actions=drop
diff --git a/lte/gateway/python/magma/pipelined/tests/snapshots/test_restart_resilience.RestartResilienceTest.test_url_redirect.snapshot b/lte/gateway/python/magma/pipelined/tests/snapshots/test_restart_resilience.RestartResilienceTest.test_url_redirect.snapshot
index 35e8ee29cf40..717f763d333b 100644
--- a/lte/gateway/python/magma/pipelined/tests/snapshots/test_restart_resilience.RestartResilienceTest.test_url_redirect.snapshot
+++ b/lte/gateway/python/magma/pipelined/tests/snapshots/test_restart_resilience.RestartResilienceTest.test_url_redirect.snapshot
@@ -1,13 +1,13 @@
cookie=0x0, table=mme(main_table), n_packets=1, n_bytes=54, priority=65535,ip,nw_src=192.168.128.74 actions=load:0x48c2739fd9c3->OXM_OF_METADATA[],load:0x1->NXM_NX_REG1[],resubmit(,enforcement(main_table))
cookie=0x0, table=mme(main_table), n_packets=0, n_bytes=0, priority=65535,ip,nw_dst=192.168.128.74 actions=load:0x48c2739fd9c3->OXM_OF_METADATA[],load:0x10->NXM_NX_REG1[],resubmit(,enforcement(main_table))
- cookie=0x6, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65533,ip,reg1=0x1,metadata=0x48c2739fd9c3,nw_src=192.168.128.74,nw_dst=185.128.101.5 actions=note:b'redir_test',set_field:0x6->reg2,set_field:0->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
- cookie=0x6, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65533,ip,reg1=0x10,metadata=0x48c2739fd9c3,nw_src=185.128.101.5,nw_dst=192.168.128.74 actions=note:b'redir_test',set_field:0x6->reg2,set_field:0->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
- cookie=0x6, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65533,ip,reg1=0x1,metadata=0x48c2739fd9c3,nw_src=192.168.128.74,nw_dst=185.128.121.4 actions=note:b'redir_test',set_field:0x6->reg2,set_field:0->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
- cookie=0x6, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65533,ip,reg1=0x10,metadata=0x48c2739fd9c3,nw_src=185.128.121.4,nw_dst=192.168.128.74 actions=note:b'redir_test',set_field:0x6->reg2,set_field:0->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
- cookie=0x6, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65532,udp,reg1=0x10,metadata=0x48c2739fd9c3,tp_src=53 actions=note:b'redir_test',set_field:0x6->reg2,set_field:0->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
- cookie=0x6, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65532,tcp,reg1=0x10,metadata=0x48c2739fd9c3,tp_src=53 actions=note:b'redir_test',set_field:0x6->reg2,set_field:0->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
- cookie=0x6, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65532,udp,reg1=0x1,metadata=0x48c2739fd9c3,tp_dst=53 actions=note:b'redir_test',set_field:0x6->reg2,set_field:0->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
- cookie=0x6, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65532,tcp,reg1=0x1,metadata=0x48c2739fd9c3,tp_dst=53 actions=note:b'redir_test',set_field:0x6->reg2,set_field:0->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
+ cookie=0x6, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65533,ip,reg1=0x1,metadata=0x48c2739fd9c3,nw_src=192.168.128.74,nw_dst=185.128.101.5 actions=note:b'redir_test',set_field:0x6->reg2,set_field:0x1->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
+ cookie=0x6, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65533,ip,reg1=0x10,metadata=0x48c2739fd9c3,nw_src=185.128.101.5,nw_dst=192.168.128.74 actions=note:b'redir_test',set_field:0x6->reg2,set_field:0x1->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
+ cookie=0x6, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65533,ip,reg1=0x1,metadata=0x48c2739fd9c3,nw_src=192.168.128.74,nw_dst=185.128.121.4 actions=note:b'redir_test',set_field:0x6->reg2,set_field:0x1->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
+ cookie=0x6, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65533,ip,reg1=0x10,metadata=0x48c2739fd9c3,nw_src=185.128.121.4,nw_dst=192.168.128.74 actions=note:b'redir_test',set_field:0x6->reg2,set_field:0x1->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
+ cookie=0x6, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65532,udp,reg1=0x10,metadata=0x48c2739fd9c3,tp_src=53 actions=note:b'redir_test',set_field:0x6->reg2,set_field:0x1->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
+ cookie=0x6, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65532,tcp,reg1=0x10,metadata=0x48c2739fd9c3,tp_src=53 actions=note:b'redir_test',set_field:0x6->reg2,set_field:0x1->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
+ cookie=0x6, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65532,udp,reg1=0x1,metadata=0x48c2739fd9c3,tp_dst=53 actions=note:b'redir_test',set_field:0x6->reg2,set_field:0x1->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
+ cookie=0x6, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65532,tcp,reg1=0x1,metadata=0x48c2739fd9c3,tp_dst=53 actions=note:b'redir_test',set_field:0x6->reg2,set_field:0x1->reg4,resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
cookie=0x6, table=enforcement(main_table), n_packets=1, n_bytes=54, priority=65532,ip,reg0=0,reg1=0x1,metadata=0x48c2739fd9c3,nw_src=192.168.128.74 actions=note:b'redir_test',resubmit(,enforcement(scratch_table_0))
cookie=0x6, table=enforcement(main_table), n_packets=1, n_bytes=54, priority=65532,ip,reg0=0x1,reg1=0x1,metadata=0x48c2739fd9c3,nw_src=192.168.128.74 actions=note:b'redir_test',resubmit(,egress(main_table)),resubmit(,enforcement_stats(main_table)),set_field:0->reg0,set_field:0->reg3
cookie=0x6, table=enforcement(main_table), n_packets=0, n_bytes=0, priority=65532,tcp,reg1=0x10,metadata=0x48c2739fd9c3,nw_src=192.168.128.1,nw_dst=192.168.128.74,tp_src=8080,tp_dst=42132 actions=load:0x972a297a->NXM_OF_IP_SRC[],load:0x50->NXM_OF_TCP_SRC[],LOCAL
@@ -15,5 +15,5 @@
cookie=0x0, table=enforcement_stats(main_table), n_packets=0, n_bytes=0, priority=1,ip,reg1=0x10,reg2=0,reg4=0,metadata=0x48c2739fd9c3,nw_dst=192.168.128.74 actions=drop
cookie=0x0, table=enforcement_stats(main_table), n_packets=0, n_bytes=0, priority=1,ip,reg1=0x1,reg2=0,reg4=0,metadata=0x48c2739fd9c3,nw_src=192.168.128.74 actions=drop
cookie=0xfffffffffffffffe, table=enforcement_stats(main_table), n_packets=1, n_bytes=54, priority=0 actions=drop
- cookie=0x6, table=enforcement(scratch_table_0), n_packets=1, n_bytes=54, priority=65532,tcp,reg1=0x1,metadata=0x48c2739fd9c3,tp_dst=80 actions=learn(table=enforcement(main_table),priority=65532,cookie=0x6,eth_type=0x800,nw_proto=6,reg1=0x10,ip_src=192.168.128.1,NXM_OF_IP_DST[]=NXM_OF_IP_SRC[],NXM_OF_TCP_DST[]=NXM_OF_TCP_SRC[],tcp_src=8080,metadata=0x48c2739fd9c3,load:NXM_OF_IP_DST[]->NXM_OF_IP_SRC[],load:0x50->NXM_OF_TCP_SRC[],output:OXM_OF_IN_PORT[0..15]),set_field:0x1->reg0,mod_nw_dst:192.168.128.1,mod_tp_dst:8080,note:b'redir_test',set_field:0x6->reg2,set_field:0->reg4,resubmit(,enforcement(main_table))
+ cookie=0x6, table=enforcement(scratch_table_0), n_packets=1, n_bytes=54, priority=65532,tcp,reg1=0x1,metadata=0x48c2739fd9c3,tp_dst=80 actions=learn(table=enforcement(main_table),priority=65532,cookie=0x6,eth_type=0x800,nw_proto=6,reg1=0x10,ip_src=192.168.128.1,NXM_OF_IP_DST[]=NXM_OF_IP_SRC[],NXM_OF_TCP_DST[]=NXM_OF_TCP_SRC[],tcp_src=8080,metadata=0x48c2739fd9c3,load:NXM_OF_IP_DST[]->NXM_OF_IP_SRC[],load:0x50->NXM_OF_TCP_SRC[],output:OXM_OF_IN_PORT[0..15]),set_field:0x1->reg0,mod_nw_dst:192.168.128.1,mod_tp_dst:8080,note:b'redir_test',set_field:0x6->reg2,set_field:0x1->reg4,resubmit(,enforcement(main_table))
cookie=0x6, table=enforcement(scratch_table_0), n_packets=0, n_bytes=0, priority=1,metadata=0x48c2739fd9c3 actions=drop
\ No newline at end of file
diff --git a/lte/gateway/python/magma/pipelined/tests/test_access_control.py b/lte/gateway/python/magma/pipelined/tests/test_access_control.py
index 9608389e9df8..19d7257687e6 100644
--- a/lte/gateway/python/magma/pipelined/tests/test_access_control.py
+++ b/lte/gateway/python/magma/pipelined/tests/test_access_control.py
@@ -16,23 +16,34 @@
from concurrent.futures import Future
from lte.protos.mconfig.mconfigs_pb2 import PipelineD
-from magma.pipelined.app.access_control import \
- AccessControlController
+from magma.pipelined.app.access_control import AccessControlController
+from magma.pipelined.bridge_util import BridgeTools
from magma.pipelined.openflow.magma_match import MagmaMatch
from magma.pipelined.openflow.registers import Direction
+from magma.pipelined.tests.app.flow_query import RyuDirectFlowQuery as FlowQuery
from magma.pipelined.tests.app.packet_builder import IPPacketBuilder
-from magma.pipelined.tests.app.start_pipelined import TestSetup, \
- PipelinedController
-from magma.pipelined.tests.app.subscriber import SubContextConfig, default_ambr_config
-from magma.pipelined.tests.app.table_isolation import RyuDirectTableIsolator, \
- RyuForwardFlowArgsBuilder
from magma.pipelined.tests.app.packet_injector import ScapyPacketInjector
-from magma.pipelined.tests.app.flow_query import RyuDirectFlowQuery \
- as FlowQuery
-from magma.pipelined.bridge_util import BridgeTools
-from magma.pipelined.tests.pipelined_test_util import start_ryu_app_thread, \
- stop_ryu_app_thread, FlowTest, wait_after_send, FlowVerifier, \
- create_service_manager, assert_bridge_snapshot_match
+from magma.pipelined.tests.app.start_pipelined import (
+ PipelinedController,
+ TestSetup,
+)
+from magma.pipelined.tests.app.subscriber import (
+ SubContextConfig,
+ default_ambr_config,
+)
+from magma.pipelined.tests.app.table_isolation import (
+ RyuDirectTableIsolator,
+ RyuForwardFlowArgsBuilder,
+)
+from magma.pipelined.tests.pipelined_test_util import (
+ FlowTest,
+ FlowVerifier,
+ assert_bridge_snapshot_match,
+ create_service_manager,
+ start_ryu_app_thread,
+ stop_ryu_app_thread,
+ wait_after_send,
+)
from ryu.lib.packet import ether_types
diff --git a/lte/gateway/python/magma/pipelined/tests/test_arp.py b/lte/gateway/python/magma/pipelined/tests/test_arp.py
index bdf9e24bcf97..f8818acb8d87 100644
--- a/lte/gateway/python/magma/pipelined/tests/test_arp.py
+++ b/lte/gateway/python/magma/pipelined/tests/test_arp.py
@@ -11,29 +11,37 @@
limitations under the License.
"""
-import unittest
import time
+import unittest
import warnings
from concurrent.futures import Future
from lte.protos.mconfig.mconfigs_pb2 import PipelineD
-from magma.pipelined.openflow.registers import DIRECTION_REG
-from magma.pipelined.tests.app.flow_query import RyuRestFlowQuery
from magma.pipelined.app.arp import ArpController
-from magma.pipelined.tests.app.table_isolation import RyuRestTableIsolator,\
- RyuForwardFlowArgsBuilder
-from magma.pipelined.tests.app.packet_injector import ScapyPacketInjector
from magma.pipelined.bridge_util import BridgeTools
-from magma.pipelined.tests.app.packet_builder import IPPacketBuilder,\
- ARPPacketBuilder
-from magma.pipelined.tests.app.start_pipelined import TestSetup, \
- PipelinedController
from magma.pipelined.openflow.registers import DIRECTION_REG, Direction
-from magma.pipelined.tests.app.table_isolation import RyuDirectTableIsolator, \
- RyuForwardFlowArgsBuilder
-from magma.pipelined.tests.pipelined_test_util import start_ryu_app_thread, \
- stop_ryu_app_thread, create_service_manager, wait_after_send, \
- SnapshotVerifier
+from magma.pipelined.tests.app.flow_query import RyuRestFlowQuery
+from magma.pipelined.tests.app.packet_builder import (
+ ARPPacketBuilder,
+ IPPacketBuilder,
+)
+from magma.pipelined.tests.app.packet_injector import ScapyPacketInjector
+from magma.pipelined.tests.app.start_pipelined import (
+ PipelinedController,
+ TestSetup,
+)
+from magma.pipelined.tests.app.table_isolation import (
+ RyuDirectTableIsolator,
+ RyuForwardFlowArgsBuilder,
+ RyuRestTableIsolator,
+)
+from magma.pipelined.tests.pipelined_test_util import (
+ SnapshotVerifier,
+ create_service_manager,
+ start_ryu_app_thread,
+ stop_ryu_app_thread,
+ wait_after_send,
+)
def _pkt_total(stats):
diff --git a/lte/gateway/python/magma/pipelined/tests/test_arp_non_nat.py b/lte/gateway/python/magma/pipelined/tests/test_arp_non_nat.py
index ba21d4715f9d..58fa3d376b51 100644
--- a/lte/gateway/python/magma/pipelined/tests/test_arp_non_nat.py
+++ b/lte/gateway/python/magma/pipelined/tests/test_arp_non_nat.py
@@ -10,28 +10,43 @@
See the License for the specific language governing permissions and
limitations under the License.
"""
+import ipaddress
import time
import unittest
import warnings
-import ipaddress
from concurrent.futures import Future
from lte.protos.mconfig.mconfigs_pb2 import PipelineD
+from lte.protos.mobilityd_pb2 import (
+ IPAddress,
+ IPBlock,
+ ListAddedIPBlocksResponse,
+)
+from magma.pipelined.app import arp
from magma.pipelined.app.arp import ArpController
-from magma.pipelined.tests.app.packet_injector import ScapyPacketInjector
from magma.pipelined.bridge_util import BridgeTools
+from magma.pipelined.openflow.registers import (
+ DIRECTION_REG,
+ IMSI_REG,
+ Direction,
+)
from magma.pipelined.tests.app.packet_builder import ARPPacketBuilder
-from magma.pipelined.tests.app.start_pipelined import TestSetup, \
- PipelinedController
-from magma.pipelined.openflow.registers import IMSI_REG, DIRECTION_REG,\
- Direction
-from magma.pipelined.tests.app.table_isolation import RyuDirectTableIsolator, \
- RyuForwardFlowArgsBuilder
-from magma.pipelined.tests.pipelined_test_util import start_ryu_app_thread, \
- stop_ryu_app_thread, create_service_manager, wait_after_send, \
- SnapshotVerifier
-from magma.pipelined.app import arp
-from lte.protos.mobilityd_pb2 import ListAddedIPBlocksResponse, IPAddress, IPBlock
+from magma.pipelined.tests.app.packet_injector import ScapyPacketInjector
+from magma.pipelined.tests.app.start_pipelined import (
+ PipelinedController,
+ TestSetup,
+)
+from magma.pipelined.tests.app.table_isolation import (
+ RyuDirectTableIsolator,
+ RyuForwardFlowArgsBuilder,
+)
+from magma.pipelined.tests.pipelined_test_util import (
+ SnapshotVerifier,
+ create_service_manager,
+ start_ryu_app_thread,
+ stop_ryu_app_thread,
+ wait_after_send,
+)
def _pkt_total(stats):
diff --git a/lte/gateway/python/magma/pipelined/tests/test_check_quota.py b/lte/gateway/python/magma/pipelined/tests/test_check_quota.py
index 561aa18cfb1c..d11381bbcde5 100644
--- a/lte/gateway/python/magma/pipelined/tests/test_check_quota.py
+++ b/lte/gateway/python/magma/pipelined/tests/test_check_quota.py
@@ -18,17 +18,17 @@
from lte.protos.mconfig.mconfigs_pb2 import PipelineD
from lte.protos.pipelined_pb2 import SubscriberQuotaUpdate
from lte.protos.subscriberdb_pb2 import SubscriberID
+from magma.pipelined.bridge_util import BridgeTools
from magma.pipelined.tests.app.start_pipelined import (
- TestSetup,
PipelinedController,
+ TestSetup,
)
-from magma.pipelined.bridge_util import BridgeTools
from magma.pipelined.tests.pipelined_test_util import (
SnapshotVerifier,
+ create_service_manager,
start_ryu_app_thread,
stop_ryu_app_thread,
- create_service_manager,
- wait_after_send
+ wait_after_send,
)
diff --git a/lte/gateway/python/magma/pipelined/tests/test_classifier.py b/lte/gateway/python/magma/pipelined/tests/test_classifier.py
index 969e748f83d9..78e287aa17ae 100644
--- a/lte/gateway/python/magma/pipelined/tests/test_classifier.py
+++ b/lte/gateway/python/magma/pipelined/tests/test_classifier.py
@@ -11,28 +11,29 @@
limitations under the License.
"""
-import unittest
-import os
-import warnings
import ipaddress
+import os
import socket
+import unittest
+import warnings
from concurrent.futures import Future
+
+from lte.protos.mobilityd_pb2 import IPAddress
+from magma.pipelined.app.classifier import Classifier
+from magma.pipelined.bridge_util import BridgeTools
from magma.pipelined.tests.app.start_pipelined import (
- TestSetup,
PipelinedController,
+ TestSetup,
)
-from magma.pipelined.bridge_util import BridgeTools
from magma.pipelined.tests.pipelined_test_util import (
+ SnapshotVerifier,
+ assert_bridge_snapshot_match,
+ create_service_manager,
start_ryu_app_thread,
stop_ryu_app_thread,
- create_service_manager,
- assert_bridge_snapshot_match,
+ wait_after_send,
)
-from magma.pipelined.tests.pipelined_test_util import start_ryu_app_thread, \
- stop_ryu_app_thread, create_service_manager, wait_after_send, \
- SnapshotVerifier
-from magma.pipelined.app.classifier import Classifier
-from lte.protos.mobilityd_pb2 import IPAddress
+
class ClassifierTest(unittest.TestCase):
BRIDGE = 'testing_br'
diff --git a/lte/gateway/python/magma/pipelined/tests/test_classifier_traffic.py b/lte/gateway/python/magma/pipelined/tests/test_classifier_traffic.py
index d0cff3ae1d2d..287ae9986fb3 100644
--- a/lte/gateway/python/magma/pipelined/tests/test_classifier_traffic.py
+++ b/lte/gateway/python/magma/pipelined/tests/test_classifier_traffic.py
@@ -15,31 +15,31 @@
from concurrent.futures import Future
from lte.protos.mconfig.mconfigs_pb2 import PipelineD
+from lte.protos.mobilityd_pb2 import IPAddress
+from magma.pipelined.app.classifier import Classifier
from magma.pipelined.app.inout import INGRESS
+from magma.pipelined.bridge_util import BridgeTools
+from magma.pipelined.openflow.magma_match import MagmaMatch
+from magma.pipelined.tests.app.flow_query import RyuDirectFlowQuery as FlowQuery
from magma.pipelined.tests.app.packet_injector import ScapyPacketInjector
from magma.pipelined.tests.app.start_pipelined import (
- TestSetup,
PipelinedController,
+ TestSetup,
)
-from magma.pipelined.openflow.magma_match import MagmaMatch
-from magma.pipelined.tests.app.flow_query import RyuDirectFlowQuery \
- as FlowQuery
-from magma.pipelined.bridge_util import BridgeTools
from magma.pipelined.tests.pipelined_test_util import (
+ FlowTest,
+ FlowVerifier,
+ SnapshotVerifier,
+ create_service_manager,
start_ryu_app_thread,
stop_ryu_app_thread,
- create_service_manager,
wait_after_send,
- FlowVerifier,
- FlowTest,
- SnapshotVerifier,
)
from ryu.lib import hub
-from scapy.contrib.gtp import GTP_U_Header
from scapy.all import *
-from magma.pipelined.app.classifier import Classifier
-from scapy.all import Ether, IP, UDP, ARP
-from lte.protos.mobilityd_pb2 import IPAddress
+from scapy.all import ARP, IP, UDP, Ether
+from scapy.contrib.gtp import GTP_U_Header
+
class GTPTrafficTest(unittest.TestCase):
BRIDGE = 'testing_br'
diff --git a/lte/gateway/python/magma/pipelined/tests/test_conntrack.py b/lte/gateway/python/magma/pipelined/tests/test_conntrack.py
index da0cbfff6ab8..3c1bf670d02c 100644
--- a/lte/gateway/python/magma/pipelined/tests/test_conntrack.py
+++ b/lte/gateway/python/magma/pipelined/tests/test_conntrack.py
@@ -11,23 +11,34 @@
limitations under the License.
"""
+import pathlib
import unittest
import warnings
from concurrent.futures import Future
-import pathlib
from lte.protos.mconfig.mconfigs_pb2 import PipelineD
from magma.pipelined.app.conntrack import ConntrackController
-from magma.pipelined.tests.app.start_pipelined import TestSetup, \
- PipelinedController
-from magma.pipelined.tests.app.subscriber import SubContextConfig, default_ambr_config
-from magma.pipelined.tests.app.table_isolation import RyuDirectTableIsolator, \
- RyuForwardFlowArgsBuilder
-from magma.pipelined.tests.app.packet_injector import ScapyPacketInjector
from magma.pipelined.bridge_util import BridgeTools
-from magma.pipelined.tests.pipelined_test_util import start_ryu_app_thread, \
- stop_ryu_app_thread, create_service_manager, assert_bridge_snapshot_match, \
- SnapshotVerifier
+from magma.pipelined.tests.app.packet_injector import ScapyPacketInjector
+from magma.pipelined.tests.app.start_pipelined import (
+ PipelinedController,
+ TestSetup,
+)
+from magma.pipelined.tests.app.subscriber import (
+ SubContextConfig,
+ default_ambr_config,
+)
+from magma.pipelined.tests.app.table_isolation import (
+ RyuDirectTableIsolator,
+ RyuForwardFlowArgsBuilder,
+)
+from magma.pipelined.tests.pipelined_test_util import (
+ SnapshotVerifier,
+ assert_bridge_snapshot_match,
+ create_service_manager,
+ start_ryu_app_thread,
+ stop_ryu_app_thread,
+)
class ConntrackTest(unittest.TestCase):
diff --git a/lte/gateway/python/magma/pipelined/tests/test_cwf_restart_resilience.py b/lte/gateway/python/magma/pipelined/tests/test_cwf_restart_resilience.py
index e0002d9aa13f..77f983ad1fec 100644
--- a/lte/gateway/python/magma/pipelined/tests/test_cwf_restart_resilience.py
+++ b/lte/gateway/python/magma/pipelined/tests/test_cwf_restart_resilience.py
@@ -12,22 +12,32 @@
"""
import unittest
+import warnings
from concurrent.futures import Future
from unittest.mock import MagicMock
-import warnings
from lte.protos.mconfig.mconfigs_pb2 import PipelineD
from lte.protos.pipelined_pb2 import SetupUEMacRequest, UEMacFlowRequest
-from orc8r.protos.directoryd_pb2 import DirectoryRecord
-from magma.subscriberdb.sid import SIDUtils
-from magma.pipelined.bridge_util import BridgeTools
from magma.pipelined.app.base import global_epoch
-from magma.pipelined.tests.app.start_pipelined import PipelinedController, \
- TestSetup
-from magma.pipelined.tests.pipelined_test_util import FlowTest, FlowVerifier, \
- create_service_manager, start_ryu_app_thread, stop_ryu_app_thread, \
- wait_after_send, SnapshotVerifier, get_enforcement_stats, \
- wait_for_enforcement_stats, fake_cwf_setup
+from magma.pipelined.bridge_util import BridgeTools
+from magma.pipelined.tests.app.start_pipelined import (
+ PipelinedController,
+ TestSetup,
+)
+from magma.pipelined.tests.pipelined_test_util import (
+ FlowTest,
+ FlowVerifier,
+ SnapshotVerifier,
+ create_service_manager,
+ fake_cwf_setup,
+ get_enforcement_stats,
+ start_ryu_app_thread,
+ stop_ryu_app_thread,
+ wait_after_send,
+ wait_for_enforcement_stats,
+)
+from magma.subscriberdb.sid import SIDUtils
+from orc8r.protos.directoryd_pb2 import DirectoryRecord
class CWFRestartResilienceTest(unittest.TestCase):
diff --git a/lte/gateway/python/magma/pipelined/tests/test_dpi.py b/lte/gateway/python/magma/pipelined/tests/test_dpi.py
index be83f16f10fb..dfc49846669d 100644
--- a/lte/gateway/python/magma/pipelined/tests/test_dpi.py
+++ b/lte/gateway/python/magma/pipelined/tests/test_dpi.py
@@ -16,22 +16,20 @@
from concurrent.futures import Future
from lte.protos.mconfig.mconfigs_pb2 import PipelineD
-from lte.protos.policydb_pb2 import FlowMatch
from lte.protos.pipelined_pb2 import FlowRequest
-
-
+from lte.protos.policydb_pb2 import FlowMatch
+from magma.pipelined.bridge_util import BridgeTools
+from magma.pipelined.policy_converters import convert_ipv4_str_to_ip_proto
from magma.pipelined.tests.app.start_pipelined import (
- TestSetup,
PipelinedController,
+ TestSetup,
)
-from magma.pipelined.bridge_util import BridgeTools
from magma.pipelined.tests.pipelined_test_util import (
+ SnapshotVerifier,
+ create_service_manager,
start_ryu_app_thread,
stop_ryu_app_thread,
- create_service_manager,
- SnapshotVerifier,
)
-from magma.pipelined.policy_converters import convert_ipv4_str_to_ip_proto
class DPITest(unittest.TestCase):
diff --git a/lte/gateway/python/magma/pipelined/tests/test_encoding.py b/lte/gateway/python/magma/pipelined/tests/test_encoding.py
index c7e79eba99e6..9055ab3cc498 100644
--- a/lte/gateway/python/magma/pipelined/tests/test_encoding.py
+++ b/lte/gateway/python/magma/pipelined/tests/test_encoding.py
@@ -13,9 +13,13 @@
import unittest
-from magma.pipelined.encoding import encrypt_str, get_hash, encode_str, \
- decrypt_str
from lte.protos.mconfig.mconfigs_pb2 import PipelineD
+from magma.pipelined.encoding import (
+ decrypt_str,
+ encode_str,
+ encrypt_str,
+ get_hash,
+)
class EncodingTest(unittest.TestCase):
diff --git a/lte/gateway/python/magma/pipelined/tests/test_enforcement.py b/lte/gateway/python/magma/pipelined/tests/test_enforcement.py
index 1e5cfb4b6311..771cde7b3631 100644
--- a/lte/gateway/python/magma/pipelined/tests/test_enforcement.py
+++ b/lte/gateway/python/magma/pipelined/tests/test_enforcement.py
@@ -12,36 +12,55 @@
"""
import unittest
-from concurrent.futures import Future
-
import warnings
+from concurrent.futures import Future
from typing import List
from lte.protos.mconfig.mconfigs_pb2 import PipelineD
-from lte.protos.policydb_pb2 import FlowDescription, FlowMatch, PolicyRule,\
- HeaderEnrichment
-from magma.pipelined.app.enforcement import EnforcementController
from lte.protos.mobilityd_pb2 import IPAddress
+from lte.protos.pipelined_pb2 import VersionedPolicy
+from lte.protos.policydb_pb2 import (
+ FlowDescription,
+ FlowMatch,
+ HeaderEnrichment,
+ PolicyRule,
+)
+from magma.pipelined.app import he
+from magma.pipelined.app.enforcement import EnforcementController
from magma.pipelined.bridge_util import BridgeTools
-from magma.pipelined.policy_converters import flow_match_to_magma_match
-from magma.pipelined.tests.app.flow_query import RyuDirectFlowQuery \
- as FlowQuery
-from magma.pipelined.tests.app.packet_builder import IPPacketBuilder, \
- TCPPacketBuilder, IPv6PacketBuilder
+from magma.pipelined.policy_converters import (
+ convert_ipv4_str_to_ip_proto,
+ convert_ipv6_bytes_to_ip_proto,
+ flow_match_to_magma_match,
+)
+from magma.pipelined.tests.app.flow_query import RyuDirectFlowQuery as FlowQuery
+from magma.pipelined.tests.app.packet_builder import (
+ IPPacketBuilder,
+ IPv6PacketBuilder,
+ TCPPacketBuilder,
+)
from magma.pipelined.tests.app.packet_injector import ScapyPacketInjector
-from magma.pipelined.tests.app.start_pipelined import PipelinedController, \
- TestSetup
+from magma.pipelined.tests.app.start_pipelined import (
+ PipelinedController,
+ TestSetup,
+)
from magma.pipelined.tests.app.subscriber import RyuDirectSubscriberContext
-from magma.pipelined.tests.app.table_isolation import RyuDirectTableIsolator, \
- RyuForwardFlowArgsBuilder
-from magma.pipelined.policy_converters import convert_ipv4_str_to_ip_proto, \
- convert_ipv6_bytes_to_ip_proto
-from magma.pipelined.tests.pipelined_test_util import FlowTest, FlowVerifier, \
- PktsToSend, SubTest, create_service_manager, start_ryu_app_thread, \
- stop_ryu_app_thread, wait_after_send, SnapshotVerifier, \
- fake_controller_setup
-
-from magma.pipelined.app import he
+from magma.pipelined.tests.app.table_isolation import (
+ RyuDirectTableIsolator,
+ RyuForwardFlowArgsBuilder,
+)
+from magma.pipelined.tests.pipelined_test_util import (
+ FlowTest,
+ FlowVerifier,
+ PktsToSend,
+ SnapshotVerifier,
+ SubTest,
+ create_service_manager,
+ fake_controller_setup,
+ start_ryu_app_thread,
+ stop_ryu_app_thread,
+ wait_after_send,
+)
def mocked_activate_he_urls_for_ue(ip: IPAddress, rule_id, urls: List[str], imsi: str, msisdn: str):
@@ -112,6 +131,7 @@ def setUpClass(cls):
'proxy_port_name': cls.VETH,
'enable_nat': True,
'ovs_gtp_port_number': 10,
+ 'setup_type': 'LTE',
},
mconfig=PipelineD(),
loop=None,
@@ -148,7 +168,10 @@ def test_subscriber_policy(self):
action=FlowDescription.PERMIT)
]
policies = [
- PolicyRule(id='simple_match', priority=2, flow_list=flow_list1)
+ VersionedPolicy(
+ rule=PolicyRule(id='simple_match', priority=2,flow_list=flow_list1),
+ version=1,
+ ),
]
pkts_matched = 256
pkts_sent = 4096
@@ -156,7 +179,7 @@ def test_subscriber_policy(self):
# ============================ Subscriber ============================
sub_context = RyuDirectSubscriberContext(
imsi, sub_ip, self.enforcement_controller, self._tbl_num
- ).add_dynamic_rule(policies[0])
+ ).add_policy(policies[0])
isolator = RyuDirectTableIsolator(
RyuForwardFlowArgsBuilder.from_subscriber(sub_context.cfg)
.build_requests(),
@@ -206,13 +229,16 @@ def test_subscriber_ipv6_policy(self):
action=FlowDescription.PERMIT)
]
policies = [
- PolicyRule(id='simple_match', priority=2, flow_list=flow_list1)
+ VersionedPolicy(
+ rule=PolicyRule(id='simple_match', priority=2, flow_list=flow_list1),
+ version=1,
+ ),
]
# ============================ Subscriber ============================
sub_context = RyuDirectSubscriberContext(
imsi, sub_ip, self.enforcement_controller, self._tbl_num
- ).add_dynamic_rule(policies[0])
+ ).add_policy(policies[0])
isolator = RyuDirectTableIsolator(
RyuForwardFlowArgsBuilder.from_subscriber(sub_context.cfg)
.build_requests(),
@@ -246,10 +272,14 @@ def test_invalid_subscriber(self):
ip_src=convert_ipv4_str_to_ip_proto('9999.0.0.0/24')),
action=FlowDescription.DENY
)]
- policy = PolicyRule(id='invalid', priority=2, flow_list=flow_list)
+ policy = \
+ VersionedPolicy(
+ rule=PolicyRule(id='invalid', priority=2, flow_list=flow_list),
+ version=1,
+ )
invalid_sub_context = RyuDirectSubscriberContext(
imsi, sub_ip, self.enforcement_controller,
- self._tbl_num).add_dynamic_rule(policy)
+ self._tbl_num).add_policy(policy)
isolator = RyuDirectTableIsolator(
RyuForwardFlowArgsBuilder.from_subscriber(invalid_sub_context.cfg)
.build_requests(),
@@ -287,9 +317,16 @@ def test_subscriber_two_policies(self):
match=FlowMatch(ip_proto=6, direction=FlowMatch.UPLINK),
action=FlowDescription.PERMIT)
]
+
policies = [
- PolicyRule(id='match', priority=2, flow_list=flow_list1),
- PolicyRule(id='no_match', priority=2, flow_list=flow_list2)
+ VersionedPolicy(
+ rule=PolicyRule(id='match', priority=2, flow_list=flow_list1),
+ version=1,
+ ),
+ VersionedPolicy(
+ rule=PolicyRule(id='no_match', priority=2, flow_list=flow_list2),
+ version=1,
+ ),
]
pkts_sent = 42
@@ -297,8 +334,8 @@ def test_subscriber_two_policies(self):
sub_context = RyuDirectSubscriberContext(imsi, sub_ip,
self.enforcement_controller,
self._tbl_num) \
- .add_dynamic_rule(policies[0])\
- .add_dynamic_rule(policies[1])
+ .add_policy(policies[0])\
+ .add_policy(policies[1])
isolator = RyuDirectTableIsolator(
RyuForwardFlowArgsBuilder.from_subscriber(sub_context.cfg)
.build_requests(),
@@ -350,13 +387,16 @@ def test_two_subscribers(self):
action=FlowDescription.DENY)
]
- policy = PolicyRule(id='t', priority=2, flow_list=ip_match)
-
+ policy = \
+ VersionedPolicy(
+ rule=PolicyRule(id='t', priority=2, flow_list=ip_match),
+ version=1,
+ )
# =========================== Subscriber 1 ===========================
sub_context1 = RyuDirectSubscriberContext(
'IMSI208950001111111', '192.168.128.5',
self.enforcement_controller, self._tbl_num
- ).add_dynamic_rule(policy)
+ ).add_policy(policy)
isolator1 = RyuDirectTableIsolator(
RyuForwardFlowArgsBuilder.from_subscriber(sub_context1.cfg)
.build_requests(),
@@ -380,8 +420,11 @@ def test_two_subscribers(self):
sub_context2 = RyuDirectSubscriberContext(
'IMSI911500451242001', '192.168.128.100',
self.enforcement_controller, self._tbl_num
- ).add_dynamic_rule(
- PolicyRule(id='qqq', priority=2, flow_list=tcp_match)
+ ).add_policy(
+ VersionedPolicy(
+ rule=PolicyRule(id='qqq', priority=2, flow_list=tcp_match),
+ version=1,
+ )
)
isolator2 = RyuDirectTableIsolator(
RyuForwardFlowArgsBuilder.from_subscriber(sub_context2.cfg)
diff --git a/lte/gateway/python/magma/pipelined/tests/test_enforcement_stats.py b/lte/gateway/python/magma/pipelined/tests/test_enforcement_stats.py
index b234d0702b66..88dcb75e5d86 100644
--- a/lte/gateway/python/magma/pipelined/tests/test_enforcement_stats.py
+++ b/lte/gateway/python/magma/pipelined/tests/test_enforcement_stats.py
@@ -12,29 +12,49 @@
"""
import unittest
+import warnings
from concurrent.futures import Future
from unittest.mock import MagicMock
-import warnings
from lte.protos.mconfig.mconfigs_pb2 import PipelineD
-from lte.protos.policydb_pb2 import FlowDescription, FlowMatch, PolicyRule, \
- RedirectInformation
+from lte.protos.pipelined_pb2 import VersionedPolicy
+from lte.protos.policydb_pb2 import (
+ FlowDescription,
+ FlowMatch,
+ PolicyRule,
+ RedirectInformation,
+)
from magma.pipelined.app.enforcement import EnforcementController
from magma.pipelined.bridge_util import BridgeTools
-from magma.pipelined.policy_converters import convert_ipv4_str_to_ip_proto, \
- convert_ipv6_bytes_to_ip_proto
-from magma.pipelined.tests.app.packet_builder import IPPacketBuilder, \
- TCPPacketBuilder
+from magma.pipelined.policy_converters import (
+ convert_ipv4_str_to_ip_proto,
+ convert_ipv6_bytes_to_ip_proto,
+)
+from magma.pipelined.tests.app.packet_builder import (
+ IPPacketBuilder,
+ TCPPacketBuilder,
+)
from magma.pipelined.tests.app.packet_injector import ScapyPacketInjector
-from magma.pipelined.tests.app.start_pipelined import PipelinedController, \
- TestSetup
+from magma.pipelined.tests.app.start_pipelined import (
+ PipelinedController,
+ TestSetup,
+)
from magma.pipelined.tests.app.subscriber import RyuDirectSubscriberContext
-from magma.pipelined.tests.app.table_isolation import RyuDirectTableIsolator, \
- RyuForwardFlowArgsBuilder
-from magma.pipelined.tests.pipelined_test_util import create_service_manager, \
- get_enforcement_stats, start_ryu_app_thread, stop_ryu_app_thread, \
- wait_after_send, wait_for_enforcement_stats, FlowTest, SnapshotVerifier, \
- fake_controller_setup
+from magma.pipelined.tests.app.table_isolation import (
+ RyuDirectTableIsolator,
+ RyuForwardFlowArgsBuilder,
+)
+from magma.pipelined.tests.pipelined_test_util import (
+ FlowTest,
+ SnapshotVerifier,
+ create_service_manager,
+ fake_controller_setup,
+ get_enforcement_stats,
+ start_ryu_app_thread,
+ stop_ryu_app_thread,
+ wait_after_send,
+ wait_for_enforcement_stats,
+)
from scapy.all import IP
@@ -105,6 +125,7 @@ def mock_thread_safe(cmd, body):
'qos': {'enable': False},
'clean_restart': True,
'redis_enabled': False,
+ 'setup_type': 'LTE',
},
mconfig=PipelineD(),
loop=loop_mock,
@@ -161,22 +182,28 @@ def test_subscriber_policy(self):
action=FlowDescription.PERMIT)
]
policies = [
- PolicyRule(id='tx_match', priority=3, flow_list=flow_list1),
- PolicyRule(id='rx_match', priority=5, flow_list=flow_list2)
+ VersionedPolicy(
+ rule=PolicyRule(id='tx_match', priority=3, flow_list=flow_list1),
+ version=1,
+ ),
+ VersionedPolicy(
+ rule=PolicyRule(id='rx_match', priority=5, flow_list=flow_list2),
+ version=1,
+ )
]
enf_stat_name = [imsi + '|tx_match' + '|' + sub_ip,
imsi + '|rx_match' + '|' + sub_ip]
- self.service_manager.session_rule_version_mapper.update_version(
- imsi, convert_ipv4_str_to_ip_proto(sub_ip), 'tx_match')
- self.service_manager.session_rule_version_mapper.update_version(
- imsi, convert_ipv4_str_to_ip_proto(sub_ip), 'rx_match')
+ self.service_manager.session_rule_version_mapper.save_version(
+ imsi, convert_ipv4_str_to_ip_proto(sub_ip), 'tx_match', 1)
+ self.service_manager.session_rule_version_mapper.save_version(
+ imsi, convert_ipv4_str_to_ip_proto(sub_ip), 'rx_match', 1)
""" Setup subscriber, setup table_isolation to fwd pkts """
sub_context = RyuDirectSubscriberContext(
imsi, sub_ip, self.enforcement_controller,
self._main_tbl_num, self.enforcement_stats_controller
- ).add_dynamic_rule(policies[0]) \
- .add_dynamic_rule(policies[1])
+ ).add_policy(policies[0]) \
+ .add_policy(policies[1])
isolator = RyuDirectTableIsolator(
RyuForwardFlowArgsBuilder.from_subscriber(sub_context.cfg)
.build_requests(),
@@ -242,23 +269,26 @@ def test_redirect_policy(self):
imsi = 'IMSI010000000088888'
sub_ip = '192.168.128.74'
flow_list = [FlowDescription(match=FlowMatch())]
- policy = PolicyRule(
- id='redir_test', priority=3, flow_list=flow_list,
- redirect=RedirectInformation(
- support=1,
- address_type=2,
- server_address="http://about.sha.ddih.org/"
- )
+ policy = VersionedPolicy(
+ rule=PolicyRule(
+ id='redir_test', priority=3, flow_list=flow_list,
+ redirect=RedirectInformation(
+ support=1,
+ address_type=2,
+ server_address="http://about.sha.ddih.org/"
+ )
+ ),
+ version=1,
)
stat_name = imsi + '|redir_test' + '|' + sub_ip
- self.service_manager.session_rule_version_mapper.update_version(
- imsi, convert_ipv4_str_to_ip_proto(sub_ip), 'redir_test')
+ self.service_manager.session_rule_version_mapper.save_version(
+ imsi, convert_ipv4_str_to_ip_proto(sub_ip), 'redir_test', 1)
""" Setup subscriber, setup table_isolation to fwd pkts """
sub_context = RyuDirectSubscriberContext(
imsi, sub_ip, self.enforcement_controller,
self._main_tbl_num, self.enforcement_stats_controller
- ).add_dynamic_rule(policy)
+ ).add_policy(policy)
isolator = RyuDirectTableIsolator(
RyuForwardFlowArgsBuilder.from_subscriber(sub_context.cfg)
.build_requests(),
@@ -312,15 +342,18 @@ def test_rule_install(self):
direction=FlowMatch.UPLINK),
action=FlowDescription.PERMIT)
]
- policy = PolicyRule(id='rule1', priority=3, flow_list=flow_list)
- self.service_manager.session_rule_version_mapper.update_version(
- imsi, convert_ipv4_str_to_ip_proto(sub_ip), 'rule1')
+ policy = VersionedPolicy(
+ rule=PolicyRule(id='rule1', priority=3, flow_list=flow_list),
+ version=1,
+ )
+ self.service_manager.session_rule_version_mapper.save_version(
+ imsi, convert_ipv4_str_to_ip_proto(sub_ip), 'rule1', 1)
""" Setup subscriber, setup table_isolation to fwd pkts """
sub_context = RyuDirectSubscriberContext(
imsi, sub_ip, self.enforcement_controller,
self._main_tbl_num, self.enforcement_stats_controller
- ).add_dynamic_rule(policy)
+ ).add_policy(policy)
# =========================== Verification ===========================
@@ -352,15 +385,18 @@ def test_deny_rule_install(self):
direction=FlowMatch.UPLINK),
action=FlowDescription.DENY)
]
- policy = PolicyRule(id='rule1', priority=3, flow_list=flow_list)
- self.service_manager.session_rule_version_mapper.update_version(
- imsi, convert_ipv4_str_to_ip_proto(sub_ip), 'rule1')
+ policy = VersionedPolicy(
+ rule=PolicyRule(id='rule1', priority=3, flow_list=flow_list),
+ version=1,
+ )
+ self.service_manager.session_rule_version_mapper.save_version(
+ imsi, convert_ipv4_str_to_ip_proto(sub_ip), 'rule1', 1)
""" Setup subscriber, setup table_isolation to fwd pkts """
sub_context = RyuDirectSubscriberContext(
imsi, sub_ip, self.enforcement_controller,
self._main_tbl_num, self.enforcement_stats_controller
- ).add_dynamic_rule(policy)
+ ).add_policy(policy)
isolator = RyuDirectTableIsolator(
RyuForwardFlowArgsBuilder.from_subscriber(sub_context.cfg)
@@ -419,15 +455,18 @@ def test_ipv6_rule_install(self):
direction=FlowMatch.UPLINK),
action=FlowDescription.PERMIT)
]
- policy = PolicyRule(id='rule1', priority=3, flow_list=flow_list)
- self.service_manager.session_rule_version_mapper.update_version(
- imsi, convert_ipv4_str_to_ip_proto(sub_ip), 'rule1')
+ policy = VersionedPolicy(
+ rule=PolicyRule(id='rule1', priority=3, flow_list=flow_list),
+ version=1,
+ )
+ self.service_manager.session_rule_version_mapper.save_version(
+ imsi, convert_ipv4_str_to_ip_proto(sub_ip), 'rule1', 1)
""" Setup subscriber, setup table_isolation to fwd pkts """
sub_context = RyuDirectSubscriberContext(
imsi, sub_ip, self.enforcement_controller,
self._main_tbl_num, self.enforcement_stats_controller
- ).add_dynamic_rule(policy)
+ ).add_policy(policy)
# =========================== Verification ===========================
snapshot_verifier = SnapshotVerifier(self, self.BRIDGE,
@@ -459,16 +498,19 @@ def test_rule_deactivation(self):
direction=FlowMatch.UPLINK),
action=FlowDescription.PERMIT)
]
- policy = PolicyRule(id='rule1', priority=3, flow_list=flow_list)
+ policy = VersionedPolicy(
+ rule=PolicyRule(id='rule1', priority=3, flow_list=flow_list),
+ version=1,
+ )
enf_stat_name = imsi + '|rule1' + '|' + sub_ip
- self.service_manager.session_rule_version_mapper.update_version(
- imsi, convert_ipv4_str_to_ip_proto(sub_ip), 'rule1')
+ self.service_manager.session_rule_version_mapper.save_version(
+ imsi, convert_ipv4_str_to_ip_proto(sub_ip), 'rule1', 1)
""" Setup subscriber, setup table_isolation to fwd pkts """
sub_context = RyuDirectSubscriberContext(
imsi, sub_ip, self.enforcement_controller,
self._main_tbl_num, self.enforcement_stats_controller
- ).add_dynamic_rule(policy)
+ ).add_policy(policy)
isolator = RyuDirectTableIsolator(
RyuForwardFlowArgsBuilder.from_subscriber(sub_context.cfg)
.build_requests(),
@@ -496,10 +538,10 @@ def test_rule_deactivation(self):
self.enforcement_stats_controller._report_usage.reset_mock()
pkt_sender.send(packet)
self.service_manager.session_rule_version_mapper. \
- update_version(imsi, convert_ipv4_str_to_ip_proto(sub_ip),
- 'rule1')
+ save_version(imsi, convert_ipv4_str_to_ip_proto(sub_ip),
+ 'rule1', 2)
self.enforcement_controller.deactivate_rules(
- imsi, convert_ipv4_str_to_ip_proto(sub_ip), [policy.id])
+ imsi, convert_ipv4_str_to_ip_proto(sub_ip), [policy.rule.id])
wait_for_enforcement_stats(self.enforcement_stats_controller,
[enf_stat_name])
@@ -547,16 +589,19 @@ def test_rule_reactivation(self):
direction=FlowMatch.UPLINK),
action=FlowDescription.PERMIT)
]
- policy = PolicyRule(id='rule1', priority=3, flow_list=flow_list)
+ policy = VersionedPolicy(
+ rule=PolicyRule(id='rule1', priority=3, flow_list=flow_list),
+ version=1,
+ )
enf_stat_name = imsi + '|rule1' + '|' + sub_ip
- self.service_manager.session_rule_version_mapper.update_version(
- imsi, convert_ipv4_str_to_ip_proto(sub_ip), 'rule1')
+ self.service_manager.session_rule_version_mapper.save_version(
+ imsi, convert_ipv4_str_to_ip_proto(sub_ip), 'rule1', 1)
""" Setup subscriber, setup table_isolation to fwd pkts """
sub_context = RyuDirectSubscriberContext(
imsi, sub_ip, self.enforcement_controller,
self._main_tbl_num, self.enforcement_stats_controller
- ).add_dynamic_rule(policy)
+ ).add_policy(policy)
isolator = RyuDirectTableIsolator(
RyuForwardFlowArgsBuilder.from_subscriber(sub_context.cfg)
.build_requests(),
@@ -586,10 +631,11 @@ def test_rule_reactivation(self):
self.enforcement_stats_controller._report_usage.reset_mock()
self.service_manager.session_rule_version_mapper. \
- update_version(imsi, convert_ipv4_str_to_ip_proto(sub_ip),
- 'rule1')
+ save_version(imsi, convert_ipv4_str_to_ip_proto(sub_ip),
+ 'rule1', 2)
self.enforcement_controller.deactivate_rules(
- imsi, convert_ipv4_str_to_ip_proto(sub_ip), [policy.id])
+ imsi, convert_ipv4_str_to_ip_proto(sub_ip), [policy.rule.id])
+ policy.version=2
self.enforcement_controller.activate_rules(
imsi, None, None, convert_ipv4_str_to_ip_proto(sub_ip), None,
[policy])
diff --git a/lte/gateway/python/magma/pipelined/tests/test_gy.py b/lte/gateway/python/magma/pipelined/tests/test_gy.py
index 1f2600203bee..76587c7f034a 100644
--- a/lte/gateway/python/magma/pipelined/tests/test_gy.py
+++ b/lte/gateway/python/magma/pipelined/tests/test_gy.py
@@ -11,32 +11,53 @@
limitations under the License.
"""
-import warnings
import unittest
+import warnings
from concurrent.futures import Future
from unittest.mock import MagicMock
from lte.protos.mconfig.mconfigs_pb2 import PipelineD
-from lte.protos.policydb_pb2 import FlowDescription, FlowMatch, PolicyRule, \
- RedirectInformation
+from lte.protos.pipelined_pb2 import VersionedPolicy
+from lte.protos.policydb_pb2 import (
+ FlowDescription,
+ FlowMatch,
+ PolicyRule,
+ RedirectInformation,
+)
from magma.pipelined.app.gy import GYController
from magma.pipelined.bridge_util import BridgeTools
-from magma.pipelined.policy_converters import flow_match_to_magma_match, \
- convert_ipv4_str_to_ip_proto
-from magma.pipelined.tests.app.packet_builder import TCPPacketBuilder, \
- IPPacketBuilder
+from magma.pipelined.policy_converters import (
+ convert_ipv4_str_to_ip_proto,
+ flow_match_to_magma_match,
+)
+from magma.pipelined.tests.app.flow_query import RyuDirectFlowQuery as FlowQuery
+from magma.pipelined.tests.app.packet_builder import (
+ IPPacketBuilder,
+ TCPPacketBuilder,
+)
from magma.pipelined.tests.app.packet_injector import ScapyPacketInjector
-from magma.pipelined.tests.app.start_pipelined import PipelinedController, \
- TestSetup
+from magma.pipelined.tests.app.start_pipelined import (
+ PipelinedController,
+ TestSetup,
+)
from magma.pipelined.tests.app.subscriber import RyuDirectSubscriberContext
-from magma.pipelined.tests.app.table_isolation import RyuDirectTableIsolator, \
- RyuForwardFlowArgsBuilder
-from magma.pipelined.tests.app.flow_query import RyuDirectFlowQuery \
- as FlowQuery
-from magma.pipelined.tests.pipelined_test_util import SnapshotVerifier, \
- create_service_manager, start_ryu_app_thread, fake_controller_setup, \
- stop_ryu_app_thread, wait_after_send, FlowTest, SnapshotVerifier, \
- SubTest, FlowVerifier, PktsToSend
+from magma.pipelined.tests.app.table_isolation import (
+ RyuDirectTableIsolator,
+ RyuForwardFlowArgsBuilder,
+)
+from magma.pipelined.tests.pipelined_test_util import (
+ FlowTest,
+ FlowVerifier,
+ PktsToSend,
+ SnapshotVerifier,
+ SubTest,
+ create_service_manager,
+ fake_controller_setup,
+ start_ryu_app_thread,
+ stop_ryu_app_thread,
+ wait_after_send,
+)
+
class GYTableTest(unittest.TestCase):
BRIDGE = 'testing_br'
@@ -132,19 +153,22 @@ def test_subscriber_redirect_policy(self):
"about.sha.ddih.org", lambda: redirect_ips, max_age=42
)
flow_list = [FlowDescription(match=FlowMatch())]
- policy = PolicyRule(
- id='redir_test', priority=3, flow_list=flow_list,
- redirect=RedirectInformation(
- support=1,
- address_type=2,
- server_address="http://about.sha.ddih.org/"
- )
+ policy = VersionedPolicy(
+ rule= PolicyRule(
+ id='redir_test', priority=3, flow_list=flow_list,
+ redirect=RedirectInformation(
+ support=1,
+ address_type=2,
+ server_address="http://about.sha.ddih.org/"
+ )
+ ),
+ version=1,
)
# ============================ Subscriber ============================
sub_context = RyuDirectSubscriberContext(
imsi, sub_ip, self.gy_controller, self._tbl_num
- ).add_dynamic_rule(policy)
+ ).add_policy(policy)
isolator = RyuDirectTableIsolator(
RyuForwardFlowArgsBuilder.from_subscriber(sub_context.cfg)
.build_requests(),
@@ -183,7 +207,10 @@ def test_subscriber_restrict_policy(self):
action=FlowDescription.PERMIT)
]
policies = [
- PolicyRule(id='restrict_match', priority=2, flow_list=flow_list1)
+ VersionedPolicy(
+ rule=PolicyRule(id='restrict_match', priority=2, flow_list=flow_list1),
+ version=1,
+ )
]
pkts_matched = 256
pkts_sent = 4096
@@ -191,7 +218,7 @@ def test_subscriber_restrict_policy(self):
# ============================ Subscriber ============================
sub_context = RyuDirectSubscriberContext(
imsi, sub_ip, self.gy_controller, self._tbl_num
- ).add_dynamic_rule(policies[0])
+ ).add_policy(policies[0])
isolator = RyuDirectTableIsolator(
RyuForwardFlowArgsBuilder.from_subscriber(sub_context.cfg)
.build_requests(),
diff --git a/lte/gateway/python/magma/pipelined/tests/test_he.py b/lte/gateway/python/magma/pipelined/tests/test_he.py
index 27c6e659c849..4898f0ad2ead 100644
--- a/lte/gateway/python/magma/pipelined/tests/test_he.py
+++ b/lte/gateway/python/magma/pipelined/tests/test_he.py
@@ -18,32 +18,40 @@
from lte.protos.mconfig.mconfigs_pb2 import PipelineD
from lte.protos.mobilityd_pb2 import IPAddress
-
-from magma.pipelined.app.he import HeaderEnrichmentController
+from lte.protos.pipelined_pb2 import VersionedPolicy
+from lte.protos.policydb_pb2 import (
+ FlowDescription,
+ FlowMatch,
+ HeaderEnrichment,
+ PolicyRule,
+)
+from magma.pipelined.app import he
from magma.pipelined.app.enforcement import EnforcementController
-from lte.protos.policydb_pb2 import FlowDescription, FlowMatch, PolicyRule, \
- HeaderEnrichment
-
+from magma.pipelined.app.he import HeaderEnrichmentController
from magma.pipelined.bridge_util import BridgeTools
-from magma.pipelined.tests.app.subscriber import RyuDirectSubscriberContext
-
-from magma.pipelined.tests.app.start_pipelined import TestSetup, \
- PipelinedController
-from magma.pipelined.tests.pipelined_test_util import start_ryu_app_thread, \
- stop_ryu_app_thread, create_service_manager, wait_after_send, \
- SnapshotVerifier
-from magma.pipelined.policy_converters import convert_ip_str_to_ip_proto
-
-from magma.pipelined.tests.app.table_isolation import RyuDirectTableIsolator, \
- RyuForwardFlowArgsBuilder
-
-from magma.pipelined.openflow.messages import MessageHub
-from magma.pipelined.openflow.messages import MsgChannel
-from magma.pipelined.app import he
+from magma.pipelined.openflow.messages import MessageHub, MsgChannel
from magma.pipelined.openflow.registers import Direction
-from magma.pipelined.policy_converters import convert_ipv4_str_to_ip_proto
-
-from magma.pipelined.tests.pipelined_test_util import fake_controller_setup
+from magma.pipelined.policy_converters import (
+ convert_ip_str_to_ip_proto,
+ convert_ipv4_str_to_ip_proto,
+)
+from magma.pipelined.tests.app.start_pipelined import (
+ PipelinedController,
+ TestSetup,
+)
+from magma.pipelined.tests.app.subscriber import RyuDirectSubscriberContext
+from magma.pipelined.tests.app.table_isolation import (
+ RyuDirectTableIsolator,
+ RyuForwardFlowArgsBuilder,
+)
+from magma.pipelined.tests.pipelined_test_util import (
+ SnapshotVerifier,
+ create_service_manager,
+ fake_controller_setup,
+ start_ryu_app_thread,
+ stop_ryu_app_thread,
+ wait_after_send,
+)
def mocked_activate_he_urls_for_ue(ip: IPAddress, rule_id: str, urls: List[str], imsi: str, msisdn: str):
@@ -453,6 +461,7 @@ def setUpClass(cls):
'proxy_port_name': cls.VETH,
'enable_nat': True,
'ovs_gtp_port_number': 10,
+ 'setup_type': 'LTE',
},
mconfig=PipelineD(),
loop=None,
@@ -489,13 +498,16 @@ def test_subscriber_policy_with_he(self):
]
he = HeaderEnrichment(urls=['abc.com'])
policies = [
- PolicyRule(id='simple_match', priority=2, flow_list=flow_list1, he=he)
+ VersionedPolicy(
+ rule=PolicyRule(id='simple_match', priority=2, flow_list=flow_list1, he=he),
+ version=1,
+ )
]
# ============================ Subscriber ============================
sub_context = RyuDirectSubscriberContext(
imsi, sub_ip, self.enforcement_controller, self._tbl_num
- ).add_dynamic_rule(policies[0])
+ ).add_policy(policies[0])
isolator = RyuDirectTableIsolator(
RyuForwardFlowArgsBuilder.from_subscriber(sub_context.cfg)
diff --git a/lte/gateway/python/magma/pipelined/tests/test_imsi_encoding.py b/lte/gateway/python/magma/pipelined/tests/test_imsi_encoding.py
index efa91b7be45c..d8eb0aafa3bf 100644
--- a/lte/gateway/python/magma/pipelined/tests/test_imsi_encoding.py
+++ b/lte/gateway/python/magma/pipelined/tests/test_imsi_encoding.py
@@ -13,7 +13,7 @@
import unittest
-from magma.pipelined.imsi import encode_imsi, decode_imsi
+from magma.pipelined.imsi import decode_imsi, encode_imsi
class IMSIEncodingTest(unittest.TestCase):
diff --git a/lte/gateway/python/magma/pipelined/tests/test_inout.py b/lte/gateway/python/magma/pipelined/tests/test_inout.py
index e6e15e9b0c9a..9b5bce321b4c 100644
--- a/lte/gateway/python/magma/pipelined/tests/test_inout.py
+++ b/lte/gateway/python/magma/pipelined/tests/test_inout.py
@@ -15,17 +15,17 @@
import warnings
from concurrent.futures import Future
+from magma.pipelined.bridge_util import BridgeTools
from magma.pipelined.tests.app.start_pipelined import (
- TestSetup,
PipelinedController,
+ TestSetup,
)
-from magma.pipelined.bridge_util import BridgeTools
from magma.pipelined.tests.pipelined_test_util import (
- start_ryu_app_thread,
- stop_ryu_app_thread,
- create_service_manager,
assert_bridge_snapshot_match,
+ create_service_manager,
fake_inout_setup,
+ start_ryu_app_thread,
+ stop_ryu_app_thread,
)
from ryu.ofproto.ofproto_v1_4 import OFPP_LOCAL
diff --git a/lte/gateway/python/magma/pipelined/tests/test_inout_non_nat.py b/lte/gateway/python/magma/pipelined/tests/test_inout_non_nat.py
index f0ef8af8641f..00aac8d00cce 100644
--- a/lte/gateway/python/magma/pipelined/tests/test_inout_non_nat.py
+++ b/lte/gateway/python/magma/pipelined/tests/test_inout_non_nat.py
@@ -11,34 +11,32 @@
limitations under the License.
"""
import ipaddress
+import logging
import subprocess
-import time
import threading
+import time
import unittest
import warnings
from concurrent.futures import Future
-import logging
from typing import List
-from ryu.lib import hub
-
-from lte.protos.mobilityd_pb2 import IPAddress, GWInfo, IPBlock
+from lte.protos.mobilityd_pb2 import GWInfo, IPAddress, IPBlock
+from magma.pipelined.app import inout
+from magma.pipelined.bridge_util import BridgeTools
from magma.pipelined.tests.app.start_pipelined import (
- TestSetup,
PipelinedController,
+ TestSetup,
)
-from magma.pipelined.bridge_util import BridgeTools
from magma.pipelined.tests.pipelined_test_util import (
+ SnapshotVerifier,
+ create_service_manager,
+ fake_inout_setup,
start_ryu_app_thread,
stop_ryu_app_thread,
- create_service_manager,
- SnapshotVerifier,
- fake_inout_setup
)
+from ryu.lib import hub
from ryu.ofproto.ofproto_v1_4 import OFPP_LOCAL
-from magma.pipelined.app import inout
-
gw_info_map = {}
gw_info_lock = threading.RLock() # re-entrant locks
diff --git a/lte/gateway/python/magma/pipelined/tests/test_internal_pkt_ipfix_export.py b/lte/gateway/python/magma/pipelined/tests/test_internal_pkt_ipfix_export.py
index 41b71383a873..9ffa8676d85f 100644
--- a/lte/gateway/python/magma/pipelined/tests/test_internal_pkt_ipfix_export.py
+++ b/lte/gateway/python/magma/pipelined/tests/test_internal_pkt_ipfix_export.py
@@ -12,20 +12,25 @@
"""
import unittest
-from concurrent.futures import Future
-
import warnings
+from concurrent.futures import Future
from lte.protos.mconfig.mconfigs_pb2 import PipelineD
-from lte.protos.policydb_pb2 import FlowMatch
from lte.protos.pipelined_pb2 import FlowRequest
+from lte.protos.policydb_pb2 import FlowMatch
from magma.pipelined.app.dpi import DPIController
from magma.pipelined.bridge_util import BridgeTools
from magma.pipelined.policy_converters import convert_ipv4_str_to_ip_proto
-from magma.pipelined.tests.app.start_pipelined import PipelinedController, \
- TestSetup
-from magma.pipelined.tests.pipelined_test_util import create_service_manager, \
- start_ryu_app_thread, stop_ryu_app_thread, SnapshotVerifier
+from magma.pipelined.tests.app.start_pipelined import (
+ PipelinedController,
+ TestSetup,
+)
+from magma.pipelined.tests.pipelined_test_util import (
+ SnapshotVerifier,
+ create_service_manager,
+ start_ryu_app_thread,
+ stop_ryu_app_thread,
+)
class InternalPktIpfixExportTest(unittest.TestCase):
diff --git a/lte/gateway/python/magma/pipelined/tests/test_ipv6_prefix_mapper.py b/lte/gateway/python/magma/pipelined/tests/test_ipv6_prefix_mapper.py
index cd6d98307583..d33410b7b423 100644
--- a/lte/gateway/python/magma/pipelined/tests/test_ipv6_prefix_mapper.py
+++ b/lte/gateway/python/magma/pipelined/tests/test_ipv6_prefix_mapper.py
@@ -13,8 +13,11 @@
import unittest
-from magma.pipelined.ipv6_prefix_store import InterfaceIDToPrefixMapper, \
- get_ipv6_interface_id, get_ipv6_prefix
+from magma.pipelined.ipv6_prefix_store import (
+ InterfaceIDToPrefixMapper,
+ get_ipv6_interface_id,
+ get_ipv6_prefix,
+)
class InterfaceMappersTest(unittest.TestCase):
diff --git a/lte/gateway/python/magma/pipelined/tests/test_ipv6_solicitation.py b/lte/gateway/python/magma/pipelined/tests/test_ipv6_solicitation.py
index 2230835a1bc3..468e4fef3f21 100644
--- a/lte/gateway/python/magma/pipelined/tests/test_ipv6_solicitation.py
+++ b/lte/gateway/python/magma/pipelined/tests/test_ipv6_solicitation.py
@@ -16,25 +16,38 @@
from concurrent.futures import Future
from lte.protos.mconfig.mconfigs_pb2 import PipelineD
-from magma.pipelined.ipv6_prefix_store import get_ipv6_interface_id,\
- get_ipv6_prefix
-from magma.pipelined.app.ipv6_solicitation import \
- IPV6SolicitationController
-from magma.pipelined.tests.app.packet_injector import ScapyPacketInjector
+from magma.pipelined.app.ipv6_solicitation import IPV6SolicitationController
from magma.pipelined.bridge_util import BridgeTools
-from magma.pipelined.tests.app.start_pipelined import TestSetup, \
- PipelinedController
+from magma.pipelined.ipv6_prefix_store import (
+ get_ipv6_interface_id,
+ get_ipv6_prefix,
+)
from magma.pipelined.openflow.registers import DIRECTION_REG, Direction
-from magma.pipelined.tests.app.table_isolation import RyuDirectTableIsolator, \
- RyuForwardFlowArgsBuilder
-from magma.pipelined.tests.pipelined_test_util import start_ryu_app_thread, \
- stop_ryu_app_thread, create_service_manager, wait_after_send, \
- SnapshotVerifier
-
-from scapy.arch import get_if_hwaddr, get_if_addr
-from scapy.layers.l2 import ARP, Ether, Dot1Q
-from scapy.layers.inet6 import IPv6, ICMPv6ND_RS, ICMPv6NDOptSrcLLAddr, \
- ICMPv6NDOptPrefixInfo, ICMPv6ND_NS
+from magma.pipelined.tests.app.packet_injector import ScapyPacketInjector
+from magma.pipelined.tests.app.start_pipelined import (
+ PipelinedController,
+ TestSetup,
+)
+from magma.pipelined.tests.app.table_isolation import (
+ RyuDirectTableIsolator,
+ RyuForwardFlowArgsBuilder,
+)
+from magma.pipelined.tests.pipelined_test_util import (
+ SnapshotVerifier,
+ create_service_manager,
+ start_ryu_app_thread,
+ stop_ryu_app_thread,
+ wait_after_send,
+)
+from scapy.arch import get_if_addr, get_if_hwaddr
+from scapy.layers.inet6 import (
+ ICMPv6ND_NS,
+ ICMPv6ND_RS,
+ ICMPv6NDOptPrefixInfo,
+ ICMPv6NDOptSrcLLAddr,
+ IPv6,
+)
+from scapy.layers.l2 import ARP, Dot1Q, Ether
class IPV6RouterSolicitationTableTest(unittest.TestCase):
diff --git a/lte/gateway/python/magma/pipelined/tests/test_li_mirror.py b/lte/gateway/python/magma/pipelined/tests/test_li_mirror.py
index a28809403d95..667beb5b9572 100644
--- a/lte/gateway/python/magma/pipelined/tests/test_li_mirror.py
+++ b/lte/gateway/python/magma/pipelined/tests/test_li_mirror.py
@@ -15,20 +15,19 @@
import warnings
from concurrent.futures import Future
-from ryu.lib import hub
-
+from magma.pipelined.bridge_util import BridgeTools
from magma.pipelined.tests.app.start_pipelined import (
- TestSetup,
PipelinedController,
+ TestSetup,
)
-from magma.pipelined.bridge_util import BridgeTools
from magma.pipelined.tests.pipelined_test_util import (
- start_ryu_app_thread,
- stop_ryu_app_thread,
- create_service_manager,
assert_bridge_snapshot_match,
+ create_service_manager,
fake_inout_setup,
+ start_ryu_app_thread,
+ stop_ryu_app_thread,
)
+from ryu.lib import hub
from ryu.ofproto.ofproto_v1_4 import OFPP_LOCAL
diff --git a/lte/gateway/python/magma/pipelined/tests/test_ng_servicer_node.py b/lte/gateway/python/magma/pipelined/tests/test_ng_servicer_node.py
index 69b218c1958e..c1b4c11268f8 100644
--- a/lte/gateway/python/magma/pipelined/tests/test_ng_servicer_node.py
+++ b/lte/gateway/python/magma/pipelined/tests/test_ng_servicer_node.py
@@ -12,36 +12,35 @@
"""
import logging
-import warnings
-from typing import List
import subprocess
import unittest
-from unittest import TestCase
import unittest.mock
+import warnings
from collections import OrderedDict
from concurrent.futures import Future
-from unittest.mock import MagicMock
+from typing import List
+from unittest import TestCase
+from unittest.mock import MagicMock, Mock
+from lte.protos import (
+ pipelined_pb2,
+ pipelined_pb2_grpc,
+ session_manager_pb2_grpc,
+)
+from lte.protos.session_manager_pb2 import UPFAssociationState
+from magma.pipelined.app.ng_services import NGServiceController
from magma.pipelined.bridge_util import BridgeTools
from magma.pipelined.tests.app.start_pipelined import (
- TestSetup,
- PipelinedController,
- )
-
+ PipelinedController,
+ TestSetup,
+)
from magma.pipelined.tests.pipelined_test_util import (
+ create_service_manager,
start_ryu_app_thread,
stop_ryu_app_thread,
- create_service_manager,
- wait_after_send
+ wait_after_send,
)
-from magma.pipelined.app.ng_services import NGServiceController
-from lte.protos import pipelined_pb2_grpc
-from lte.protos import pipelined_pb2
-from lte.protos import session_manager_pb2_grpc
-from lte.protos.session_manager_pb2 import (
- UPFAssociationState)
-from unittest.mock import Mock, MagicMock
def mocked_send_node_state_message_success (node_message):
return True
diff --git a/lte/gateway/python/magma/pipelined/tests/test_ng_servicer_session.py b/lte/gateway/python/magma/pipelined/tests/test_ng_servicer_session.py
index 5ee774dbd1f1..d82806f5762a 100644
--- a/lte/gateway/python/magma/pipelined/tests/test_ng_servicer_session.py
+++ b/lte/gateway/python/magma/pipelined/tests/test_ng_servicer_session.py
@@ -11,28 +11,26 @@
limitations under the License.
"""
-import warnings
import unittest
-from unittest import TestCase
import unittest.mock
+import warnings
from collections import OrderedDict
from concurrent.futures import Future
+from unittest import TestCase
from unittest.mock import MagicMock
+from lte.protos.pipelined_pb2 import CauseIE
from magma.pipelined.bridge_util import BridgeTools
+from magma.pipelined.tests.app.ng_set_session_msg import CreateSessionUtil
from magma.pipelined.tests.app.start_pipelined import (
+ PipelinedController,
TestSetup,
- PipelinedController)
-
+)
from magma.pipelined.tests.pipelined_test_util import (
+ create_service_manager,
start_ryu_app_thread,
stop_ryu_app_thread,
- create_service_manager)
-
-from lte.protos.pipelined_pb2 import CauseIE
-
-from magma.pipelined.tests.app.ng_set_session_msg import (
- CreateSessionUtil)
+)
FAULTY_PDR_SESSION = 1
FAULTY_FAR_SESSION = 2
diff --git a/lte/gateway/python/magma/pipelined/tests/test_qos.py b/lte/gateway/python/magma/pipelined/tests/test_qos.py
index 310f79989f2e..d113091216fc 100644
--- a/lte/gateway/python/magma/pipelined/tests/test_qos.py
+++ b/lte/gateway/python/magma/pipelined/tests/test_qos.py
@@ -11,20 +11,28 @@
limitations under the License.
"""
import asyncio
+import logging
import subprocess
import unittest
from collections import namedtuple
from unittest.mock import MagicMock, call, patch
-from magma.pipelined.bridge_util import BridgeTools
+from lte.protos.policydb_pb2 import FlowMatch
+from magma.pipelined.bridge_util import BridgeTools
from magma.pipelined.qos.common import QosImplType, QosManager, SubscriberState
from magma.pipelined.qos.qos_meter_impl import MeterManager
from magma.pipelined.qos.qos_tc_impl import TrafficClass, argSplit, run_cmd
-from magma.pipelined.qos.types import QosInfo, get_key_json, get_key, get_subscriber_key, \
- get_subscriber_data, get_data, get_data_json
+from magma.pipelined.qos.types import (
+ QosInfo,
+ get_data,
+ get_data_json,
+ get_key,
+ get_key_json,
+ get_subscriber_data,
+ get_subscriber_key,
+)
from magma.pipelined.qos.utils import IdManager
-from lte.protos.policydb_pb2 import FlowMatch
-import logging
+
class TestQosCommon(unittest.TestCase):
def testIdManager(self):
diff --git a/lte/gateway/python/magma/pipelined/tests/test_qos_pyroute2.py b/lte/gateway/python/magma/pipelined/tests/test_qos_pyroute2.py
index 366ebb76773d..69f8f49fad7a 100755
--- a/lte/gateway/python/magma/pipelined/tests/test_qos_pyroute2.py
+++ b/lte/gateway/python/magma/pipelined/tests/test_qos_pyroute2.py
@@ -1,18 +1,16 @@
-from pyroute2 import IPRoute
-from pyroute2 import NetlinkError
-from pyroute2 import protocols
-
-import unittest
-import socket
import logging
-import traceback
-import time
import pprint
+import socket
import subprocess
+import time
+import traceback
+import unittest
+
from magma.pipelined.bridge_util import BridgeTools
from magma.pipelined.qos.qos_tc_impl import TrafficClass
-from magma.pipelined.qos.tc_ops_pyroute2 import TcOpsPyRoute2
from magma.pipelined.qos.tc_ops_cmd import TcOpsCmd
+from magma.pipelined.qos.tc_ops_pyroute2 import TcOpsPyRoute2
+from pyroute2 import IPRoute, NetlinkError, protocols
LOG = logging.getLogger('pipelined.qos.tc_rtnl')
diff --git a/lte/gateway/python/magma/pipelined/tests/test_redirect.py b/lte/gateway/python/magma/pipelined/tests/test_redirect.py
index a5d6062f26d5..4a057c1d5df6 100644
--- a/lte/gateway/python/magma/pipelined/tests/test_redirect.py
+++ b/lte/gateway/python/magma/pipelined/tests/test_redirect.py
@@ -12,29 +12,46 @@
"""
import unittest
+import warnings
from concurrent.futures import Future
from unittest.mock import MagicMock
-import warnings
from lte.protos.mconfig.mconfigs_pb2 import PipelineD
-from lte.protos.policydb_pb2 import FlowDescription, FlowMatch, PolicyRule, \
- RedirectInformation
+from lte.protos.pipelined_pb2 import VersionedPolicy
+from lte.protos.policydb_pb2 import (
+ FlowDescription,
+ FlowMatch,
+ PolicyRule,
+ RedirectInformation,
+)
from magma.pipelined.app.enforcement import EnforcementController
from magma.pipelined.bridge_util import BridgeTools
-from magma.pipelined.policy_converters import flow_match_to_magma_match, \
- convert_ipv4_str_to_ip_proto
-from magma.pipelined.tests.app.flow_query import RyuDirectFlowQuery \
- as FlowQuery
+from magma.pipelined.policy_converters import (
+ convert_ipv4_str_to_ip_proto,
+ flow_match_to_magma_match,
+)
+from magma.pipelined.tests.app.flow_query import RyuDirectFlowQuery as FlowQuery
from magma.pipelined.tests.app.packet_builder import TCPPacketBuilder
from magma.pipelined.tests.app.packet_injector import ScapyPacketInjector
-from magma.pipelined.tests.app.start_pipelined import PipelinedController, \
- TestSetup
+from magma.pipelined.tests.app.start_pipelined import (
+ PipelinedController,
+ TestSetup,
+)
from magma.pipelined.tests.app.subscriber import RyuDirectSubscriberContext
-from magma.pipelined.tests.app.table_isolation import RyuDirectTableIsolator, \
- RyuForwardFlowArgsBuilder
-from magma.pipelined.tests.pipelined_test_util import FlowTest, FlowVerifier, \
- create_service_manager, start_ryu_app_thread, stop_ryu_app_thread, \
- wait_after_send, assert_bridge_snapshot_match, fake_controller_setup
+from magma.pipelined.tests.app.table_isolation import (
+ RyuDirectTableIsolator,
+ RyuForwardFlowArgsBuilder,
+)
+from magma.pipelined.tests.pipelined_test_util import (
+ FlowTest,
+ FlowVerifier,
+ assert_bridge_snapshot_match,
+ create_service_manager,
+ fake_controller_setup,
+ start_ryu_app_thread,
+ stop_ryu_app_thread,
+ wait_after_send,
+)
class RedirectTest(unittest.TestCase):
@@ -81,6 +98,7 @@ def setUpClass(cls):
'enodeb_iface': 'eth1',
'qos': {'enable': False},
'clean_restart': True,
+ 'setup_type': 'LTE',
},
mconfig=PipelineD(),
loop=None,
@@ -121,19 +139,22 @@ def test_url_redirect(self):
imsi = 'IMSI010000000088888'
sub_ip = '192.168.128.74'
flow_list = [FlowDescription(match=FlowMatch())]
- policy = PolicyRule(
- id='redir_test', priority=3, flow_list=flow_list,
- redirect=RedirectInformation(
- support=1,
- address_type=2,
- server_address="http://about.sha.ddih.org/"
- )
+ policy = VersionedPolicy(
+ rule=PolicyRule(
+ id='redir_test', priority=3, flow_list=flow_list,
+ redirect=RedirectInformation(
+ support=1,
+ address_type=2,
+ server_address="http://about.sha.ddih.org/"
+ )
+ ),
+ version=1,
)
# ============================ Subscriber ============================
sub_context = RyuDirectSubscriberContext(
imsi, sub_ip, self.enforcement_controller, self._tbl_num
- ).add_dynamic_rule(policy)
+ ).add_policy(policy)
isolator = RyuDirectTableIsolator(
RyuForwardFlowArgsBuilder.from_subscriber(sub_context.cfg)
.build_requests(),
@@ -205,19 +226,22 @@ def test_ipv4_redirect(self):
imsi = 'IMSI012000000088888'
sub_ip = '192.168.128.74'
flow_list = [FlowDescription(match=FlowMatch())]
- policy = PolicyRule(
- id='redir_ip_test', priority=3, flow_list=flow_list,
- redirect=RedirectInformation(
- support=1,
- address_type=0,
- server_address=redirect_ip
- )
+ policy = VersionedPolicy(
+ rule=PolicyRule(
+ id='redir_ip_test', priority=3, flow_list=flow_list,
+ redirect=RedirectInformation(
+ support=1,
+ address_type=0,
+ server_address=redirect_ip
+ )
+ ),
+ version=1,
)
# ============================ Subscriber ============================
sub_context = RyuDirectSubscriberContext(
imsi, sub_ip, self.enforcement_controller, self._tbl_num
- ).add_dynamic_rule(policy)
+ ).add_policy(policy)
isolator = RyuDirectTableIsolator(
RyuForwardFlowArgsBuilder.from_subscriber(sub_context.cfg)
.build_requests(),
diff --git a/lte/gateway/python/magma/pipelined/tests/test_restart_resilience.py b/lte/gateway/python/magma/pipelined/tests/test_restart_resilience.py
index f6d799edcda0..0d4145cbc6cf 100644
--- a/lte/gateway/python/magma/pipelined/tests/test_restart_resilience.py
+++ b/lte/gateway/python/magma/pipelined/tests/test_restart_resilience.py
@@ -12,33 +12,60 @@
"""
import unittest
+import warnings
from concurrent.futures import Future
from unittest.mock import MagicMock
-import warnings
from lte.protos.mconfig.mconfigs_pb2 import PipelineD
-from lte.protos.policydb_pb2 import FlowDescription, FlowMatch, PolicyRule, \
- RedirectInformation
-from lte.protos.pipelined_pb2 import ActivateFlowsRequest, SetupFlowsRequest
-from magma.subscriberdb.sid import SIDUtils
+from lte.protos.pipelined_pb2 import (
+ ActivateFlowsRequest,
+ SetupFlowsRequest,
+ VersionedPolicy,
+)
+from lte.protos.policydb_pb2 import (
+ FlowDescription,
+ FlowMatch,
+ PolicyRule,
+ RedirectInformation,
+)
+from magma.pipelined.app.base import global_epoch
from magma.pipelined.app.enforcement import EnforcementController
from magma.pipelined.app.enforcement_stats import EnforcementStatsController
from magma.pipelined.bridge_util import BridgeTools
-from magma.pipelined.app.base import global_epoch
-from magma.pipelined.policy_converters import flow_match_to_magma_match, \
- convert_ipv4_str_to_ip_proto
-from magma.pipelined.tests.app.packet_builder import IPPacketBuilder, \
- TCPPacketBuilder
+from magma.pipelined.policy_converters import (
+ convert_ipv4_str_to_ip_proto,
+ convert_ipv6_bytes_to_ip_proto,
+ flow_match_to_magma_match,
+)
+from magma.pipelined.rule_mappers import RuleIDToNumMapper
+from magma.pipelined.tests.app.packet_builder import (
+ IPPacketBuilder,
+ TCPPacketBuilder,
+)
from magma.pipelined.tests.app.packet_injector import ScapyPacketInjector
-from magma.pipelined.tests.app.start_pipelined import PipelinedController, \
- TestSetup
-from magma.pipelined.tests.app.subscriber import RyuDirectSubscriberContext, default_ambr_config
-from magma.pipelined.tests.app.table_isolation import RyuDirectTableIsolator, \
- RyuForwardFlowArgsBuilder
-from magma.pipelined.tests.pipelined_test_util import fake_controller_setup, \
- create_service_manager, start_ryu_app_thread, stop_ryu_app_thread, \
- wait_after_send, SnapshotVerifier, get_enforcement_stats, \
- wait_for_enforcement_stats
+from magma.pipelined.tests.app.start_pipelined import (
+ PipelinedController,
+ TestSetup,
+)
+from magma.pipelined.tests.app.subscriber import (
+ RyuDirectSubscriberContext,
+ default_ambr_config,
+)
+from magma.pipelined.tests.app.table_isolation import (
+ RyuDirectTableIsolator,
+ RyuForwardFlowArgsBuilder,
+)
+from magma.pipelined.tests.pipelined_test_util import (
+ SnapshotVerifier,
+ create_service_manager,
+ fake_controller_setup,
+ get_enforcement_stats,
+ start_ryu_app_thread,
+ stop_ryu_app_thread,
+ wait_after_send,
+ wait_for_enforcement_stats,
+)
+from magma.subscriberdb.sid import SIDUtils
from scapy.all import IP
@@ -110,6 +137,7 @@ def mock_thread_safe(cmd, body):
'enodeb_iface': 'eth1',
'qos': {'enable': False},
'clean_restart': False,
+ 'setup_type': 'LTE',
},
mconfig=PipelineD(),
loop=loop_mock,
@@ -136,6 +164,73 @@ def tearDownClass(cls):
stop_ryu_app_thread(cls.thread)
BridgeTools.destroy_bridge(cls.BRIDGE)
+ def test_enforcement_ipv6_restart(self):
+ """
+ Adds rules using the setup feature
+
+ 1) Empty SetupFlowsRequest
+ - assert default flows
+ 2) Add imsi with ipv6 policy
+ - assert everything is properly added
+ """
+ fake_controller_setup(
+ enf_controller=self.enforcement_controller,
+ enf_stats_controller=self.enforcement_stats_controller,
+ startup_flow_controller=self.startup_flows_contoller)
+ snapshot_verifier = SnapshotVerifier(self, self.BRIDGE,
+ self.service_manager,
+ 'default_flows')
+ with snapshot_verifier:
+ pass
+
+ imsi = 'IMSI010000002388888'
+ sub_ip = b'fe80:24c3:d0ff:fef3:9d21:4407:d337:1928'
+
+ flow_list = [FlowDescription(
+ match=FlowMatch(
+ ip_dst=convert_ipv6_bytes_to_ip_proto(b'fe80::'),
+ direction=FlowMatch.UPLINK),
+ action=FlowDescription.PERMIT)
+ ]
+ policies = [
+ VersionedPolicy(
+ rule=PolicyRule(id='ipv6_rule', priority=2, flow_list=flow_list),
+ version=1,
+ ),
+ ]
+ enf_stat_name = [imsi + '|ipv6_rule' + '|' + str(sub_ip)]
+ setup_flows_request = SetupFlowsRequest(
+ requests=[ActivateFlowsRequest(
+ sid=SIDUtils.to_pb(imsi),
+ ipv6_addr=sub_ip,
+ policies=policies,
+ )],
+ epoch=global_epoch
+ )
+
+ fake_controller_setup(
+ enf_controller=self.enforcement_controller,
+ enf_stats_controller=self.enforcement_stats_controller,
+ startup_flow_controller=self.startup_flows_contoller,
+ setup_flows_request=setup_flows_request)
+ snapshot_verifier = SnapshotVerifier(self, self.BRIDGE,
+ self.service_manager,
+ 'after_restart')
+ with snapshot_verifier:
+ pass
+
+ fake_controller_setup(
+ enf_controller=self.enforcement_controller,
+ enf_stats_controller=self.enforcement_stats_controller,
+ startup_flow_controller=self.startup_flows_contoller)
+ snapshot_verifier = SnapshotVerifier(self, self.BRIDGE,
+ self.service_manager,
+ 'default_flows')
+
+ with snapshot_verifier:
+ pass
+
+
def test_enforcement_restart(self):
"""
Adds rules using the setup feature
@@ -149,6 +244,8 @@ def test_enforcement_restart(self):
4) Empty SetupFlowsRequest
- assert default flows
"""
+ self.enforcement_controller._rule_mapper = RuleIDToNumMapper()
+ self.enforcement_stats_controller._rule_mapper = RuleIDToNumMapper()
fake_controller_setup(
enf_controller=self.enforcement_controller,
enf_stats_controller=self.enforcement_stats_controller,
@@ -181,35 +278,45 @@ def test_enforcement_restart(self):
action=FlowDescription.PERMIT)
]
policies1 = [
- PolicyRule(id='sub1_rule_temp', priority=2, flow_list=flow_list1),
+ VersionedPolicy(
+ rule=PolicyRule(id='sub1_rule_temp', priority=2, flow_list=flow_list1),
+ version=1,
+ )
]
policies2 = [
- PolicyRule(id='sub2_rule_keep', priority=3, flow_list=flow_list2)
+ VersionedPolicy(
+ rule=PolicyRule(id='sub2_rule_keep', priority=3, flow_list=flow_list2),
+ version=1,
+ )
]
enf_stat_name = [imsi1 + '|sub1_rule_temp' + '|' + sub2_ip,
imsi2 + '|sub2_rule_keep' + '|' + sub2_ip]
- self.service_manager.session_rule_version_mapper.update_version(
- imsi1, convert_ipv4_str_to_ip_proto(sub2_ip), 'sub1_rule_temp')
- self.service_manager.session_rule_version_mapper.update_version(
- imsi2, convert_ipv4_str_to_ip_proto(sub2_ip), 'sub2_rule_keep')
+ self.service_manager.session_rule_version_mapper.save_version(
+ imsi1, convert_ipv4_str_to_ip_proto(sub2_ip), 'sub1_rule_temp', 1)
+ self.service_manager.session_rule_version_mapper.save_version(
+ imsi2, convert_ipv4_str_to_ip_proto(sub2_ip), 'sub2_rule_keep', 1)
setup_flows_request = SetupFlowsRequest(
requests=[
ActivateFlowsRequest(
sid=SIDUtils.to_pb(imsi1),
ip_addr=sub2_ip,
- dynamic_rules=policies1
+ policies=policies1
),
ActivateFlowsRequest(
sid=SIDUtils.to_pb(imsi2),
ip_addr=sub2_ip,
- dynamic_rules=policies2
+ policies=policies2
),
],
epoch=global_epoch
)
+ # Simulate clearing the dict
+ self.service_manager.session_rule_version_mapper\
+ ._version_by_imsi_and_rule = {}
+
fake_controller_setup(
enf_controller=self.enforcement_controller,
enf_stats_controller=self.enforcement_stats_controller,
@@ -242,18 +349,22 @@ def test_enforcement_restart(self):
action=FlowDescription.PERMIT)
]
policies = [
- PolicyRule(id='sub2_new_rule', priority=2, flow_list=flow_list1),
- PolicyRule(id='sub2_rule_keep', priority=3, flow_list=flow_list2)
+ VersionedPolicy(
+ rule=PolicyRule(id='sub2_new_rule', priority=2, flow_list=flow_list1),
+ version=1,
+ ),
+ VersionedPolicy(
+ rule=PolicyRule(id='sub2_rule_keep', priority=3, flow_list=flow_list2),
+ version=1,
+ ),
]
- self.service_manager.session_rule_version_mapper.update_version(
- imsi2, convert_ipv4_str_to_ip_proto(sub2_ip), 'sub2_new_rule')
enf_stat_name = [imsi2 + '|sub2_new_rule' + '|' + sub2_ip,
imsi2 + '|sub2_rule_keep' + '|' + sub2_ip]
setup_flows_request = SetupFlowsRequest(
requests=[ActivateFlowsRequest(
sid=SIDUtils.to_pb(imsi2),
ip_addr=sub2_ip,
- dynamic_rules=policies
+ policies=policies,
)],
epoch=global_epoch
)
@@ -323,22 +434,28 @@ def test_enforcement_stats_restart(self):
action=FlowDescription.PERMIT)
]
policies = [
- PolicyRule(id='tx_match', priority=3, flow_list=flow_list1),
- PolicyRule(id='rx_match', priority=5, flow_list=flow_list2)
+ VersionedPolicy(
+ rule=PolicyRule(id='tx_match', priority=3, flow_list=flow_list1),
+ version=1,
+ ),
+ VersionedPolicy(
+ rule=PolicyRule(id='rx_match', priority=5, flow_list=flow_list2),
+ version=1,
+ ),
]
enf_stat_name = [imsi + '|tx_match' + '|' + sub_ip,
imsi + '|rx_match' + '|' + sub_ip]
- self.service_manager.session_rule_version_mapper.update_version(
- imsi, convert_ipv4_str_to_ip_proto(sub_ip), 'tx_match')
- self.service_manager.session_rule_version_mapper.update_version(
- imsi, convert_ipv4_str_to_ip_proto(sub_ip), 'rx_match')
+ self.service_manager.session_rule_version_mapper.save_version(
+ imsi, convert_ipv4_str_to_ip_proto(sub_ip), 'tx_match', 1)
+ self.service_manager.session_rule_version_mapper.save_version(
+ imsi, convert_ipv4_str_to_ip_proto(sub_ip), 'rx_match', 1)
""" Setup subscriber, setup table_isolation to fwd pkts """
sub_context = RyuDirectSubscriberContext(
imsi, sub_ip, self.enforcement_controller,
self._enforcement_tbl_num, self.enforcement_stats_controller,
nuke_flows_on_exit=False
- ).add_dynamic_rule(policies[0]).add_dynamic_rule(policies[1])
+ ).add_policy(policies[0]).add_policy(policies[1])
isolator = RyuDirectTableIsolator(
RyuForwardFlowArgsBuilder.from_subscriber(sub_context.cfg)
.build_requests(),
@@ -393,7 +510,7 @@ def test_enforcement_stats_restart(self):
ActivateFlowsRequest(
sid=SIDUtils.to_pb(imsi),
ip_addr=sub_ip,
- dynamic_rules=[policies[0], policies[1]]
+ policies=[policies[0], policies[1]]
),
],
epoch=global_epoch
@@ -452,7 +569,7 @@ def test_url_redirect(self):
ActivateFlowsRequest(
sid=SIDUtils.to_pb(imsi),
ip_addr=sub_ip,
- dynamic_rules=[policy]
+ policies=[VersionedPolicy(rule=policy, version=1)]
),
],
epoch=global_epoch
diff --git a/lte/gateway/python/magma/pipelined/tests/test_rule_mappers.py b/lte/gateway/python/magma/pipelined/tests/test_rule_mappers.py
index d19a8ea29fb8..3618e50eedd2 100644
--- a/lte/gateway/python/magma/pipelined/tests/test_rule_mappers.py
+++ b/lte/gateway/python/magma/pipelined/tests/test_rule_mappers.py
@@ -12,12 +12,12 @@
"""
import unittest
-import fakeredis
-from unittest.mock import MagicMock
from unittest import mock
+from unittest.mock import MagicMock
-from magma.pipelined.rule_mappers import SessionRuleToVersionMapper
+import fakeredis
from magma.pipelined.policy_converters import convert_ipv4_str_to_ip_proto
+from magma.pipelined.rule_mappers import SessionRuleToVersionMapper
class RuleMappersTest(unittest.TestCase):
@@ -34,29 +34,30 @@ def test_session_rule_version_mapper(self):
rule_ids = ['rule1', 'rule2']
imsi = 'IMSI12345'
ip_addr = '1.2.3.4'
- self._session_rule_version_mapper.update_version(
- imsi, convert_ipv4_str_to_ip_proto(ip_addr), rule_ids[0])
+ self._session_rule_version_mapper.save_version(
+ imsi, convert_ipv4_str_to_ip_proto(ip_addr), rule_ids[0], 1)
self.assertEqual(
self._session_rule_version_mapper.get_version(
imsi, convert_ipv4_str_to_ip_proto(ip_addr), rule_ids[0]),
1)
- self._session_rule_version_mapper.update_version(
- imsi, convert_ipv4_str_to_ip_proto(ip_addr), rule_ids[1])
+ self._session_rule_version_mapper.save_version(
+ imsi, convert_ipv4_str_to_ip_proto(ip_addr), rule_ids[1], 1)
self.assertEqual(
self._session_rule_version_mapper.get_version(
imsi, convert_ipv4_str_to_ip_proto(ip_addr), rule_ids[1]),
1)
- self._session_rule_version_mapper.update_version(
- imsi, convert_ipv4_str_to_ip_proto(ip_addr), rule_ids[0])
+ self._session_rule_version_mapper.save_version(
+ imsi, convert_ipv4_str_to_ip_proto(ip_addr), rule_ids[0], 2)
self.assertEqual(
self._session_rule_version_mapper.get_version(
imsi, convert_ipv4_str_to_ip_proto(ip_addr), rule_ids[0]),
2)
# Test updating version for all rules of a subscriber
- self._session_rule_version_mapper.update_version(imsi, None)
+ self._session_rule_version_mapper.update_all_ue_versions(imsi,
+ convert_ipv4_str_to_ip_proto(ip_addr))
self.assertEqual(
self._session_rule_version_mapper.get_version(
@@ -70,29 +71,29 @@ def test_session_rule_version_mapper(self):
def test_session_rule_version_mapper_cwf(self):
rule_ids = ['rule1', 'rule2']
imsi = 'IMSI12345'
- self._session_rule_version_mapper.update_version(
- imsi, None, rule_ids[0])
+ self._session_rule_version_mapper.save_version(
+ imsi, None, rule_ids[0], 1)
self.assertEqual(
self._session_rule_version_mapper.get_version(
imsi, None, rule_ids[0]),
1)
- self._session_rule_version_mapper.update_version(
- imsi, None, rule_ids[1])
+ self._session_rule_version_mapper.save_version(
+ imsi, None, rule_ids[1], 1)
self.assertEqual(
self._session_rule_version_mapper.get_version(
imsi, None, rule_ids[1]),
1)
- self._session_rule_version_mapper.update_version(
- imsi, None, rule_ids[0])
+ self._session_rule_version_mapper.save_version(
+ imsi, None, rule_ids[0], 2)
self.assertEqual(
self._session_rule_version_mapper.get_version(
imsi, None, rule_ids[0]),
2)
# Test updating version for all rules of a subscriber
- self._session_rule_version_mapper.update_version(imsi, None)
+ self._session_rule_version_mapper.update_all_ue_versions(imsi, None)
self.assertEqual(
self._session_rule_version_mapper.get_version(
diff --git a/lte/gateway/python/magma/pipelined/tests/test_service_manager.py b/lte/gateway/python/magma/pipelined/tests/test_service_manager.py
index e11ea092eab4..3a72b05cdee8 100644
--- a/lte/gateway/python/magma/pipelined/tests/test_service_manager.py
+++ b/lte/gateway/python/magma/pipelined/tests/test_service_manager.py
@@ -13,21 +13,21 @@
import unittest
from collections import OrderedDict
-import fakeredis
-from unittest.mock import MagicMock
from unittest import mock
+from unittest.mock import MagicMock
-from magma.pipelined.app.base import ControllerType
+import fakeredis
+from lte.protos.mconfig.mconfigs_pb2 import PipelineD
from magma.pipelined.app.access_control import AccessControlController
from magma.pipelined.app.arp import ArpController
-from lte.protos.mconfig.mconfigs_pb2 import PipelineD
+from magma.pipelined.app.base import ControllerType
from magma.pipelined.app.dpi import DPIController
-from magma.pipelined.app.gy import GYController
from magma.pipelined.app.enforcement import EnforcementController
from magma.pipelined.app.enforcement_stats import EnforcementStatsController
-from magma.pipelined.app.inout import INGRESS, EGRESS, PHYSICAL_TO_LOGICAL
-from magma.pipelined.app.ipfix import IPFIXController
+from magma.pipelined.app.gy import GYController
from magma.pipelined.app.he import HeaderEnrichmentController
+from magma.pipelined.app.inout import EGRESS, INGRESS, PHYSICAL_TO_LOGICAL
+from magma.pipelined.app.ipfix import IPFIXController
from magma.pipelined.service_manager import (
ServiceManager,
TableNumException,
diff --git a/lte/gateway/python/magma/pipelined/tests/test_tunnel_learn.py b/lte/gateway/python/magma/pipelined/tests/test_tunnel_learn.py
index b7904f0fbcfc..d82eb2dd7d32 100644
--- a/lte/gateway/python/magma/pipelined/tests/test_tunnel_learn.py
+++ b/lte/gateway/python/magma/pipelined/tests/test_tunnel_learn.py
@@ -17,16 +17,27 @@
from lte.protos.mconfig.mconfigs_pb2 import PipelineD
from magma.pipelined.app.tunnel_learn import TunnelLearnController
-from magma.pipelined.tests.app.start_pipelined import TestSetup, \
- PipelinedController
+from magma.pipelined.bridge_util import BridgeTools
from magma.pipelined.tests.app.packet_builder import IPPacketBuilder
-from magma.pipelined.tests.app.subscriber import SubContextConfig, default_ambr_config
-from magma.pipelined.tests.app.table_isolation import RyuDirectTableIsolator, \
- RyuForwardFlowArgsBuilder
from magma.pipelined.tests.app.packet_injector import ScapyPacketInjector
-from magma.pipelined.bridge_util import BridgeTools
-from magma.pipelined.tests.pipelined_test_util import start_ryu_app_thread, \
- stop_ryu_app_thread, create_service_manager, assert_bridge_snapshot_match
+from magma.pipelined.tests.app.start_pipelined import (
+ PipelinedController,
+ TestSetup,
+)
+from magma.pipelined.tests.app.subscriber import (
+ SubContextConfig,
+ default_ambr_config,
+)
+from magma.pipelined.tests.app.table_isolation import (
+ RyuDirectTableIsolator,
+ RyuForwardFlowArgsBuilder,
+)
+from magma.pipelined.tests.pipelined_test_util import (
+ assert_bridge_snapshot_match,
+ create_service_manager,
+ start_ryu_app_thread,
+ stop_ryu_app_thread,
+)
class TunnelLearnTest(unittest.TestCase):
diff --git a/lte/gateway/python/magma/pipelined/tests/test_ue_mac.py b/lte/gateway/python/magma/pipelined/tests/test_ue_mac.py
index c8511815acee..fae42dfa092f 100644
--- a/lte/gateway/python/magma/pipelined/tests/test_ue_mac.py
+++ b/lte/gateway/python/magma/pipelined/tests/test_ue_mac.py
@@ -16,24 +16,23 @@
from concurrent.futures import Future
from magma.pipelined.app.ue_mac import UEMacAddressController
+from magma.pipelined.bridge_util import BridgeTools
+from magma.pipelined.openflow.magma_match import MagmaMatch
+from magma.pipelined.tests.app.flow_query import RyuDirectFlowQuery as FlowQuery
from magma.pipelined.tests.app.packet_builder import EtherPacketBuilder
from magma.pipelined.tests.app.packet_injector import ScapyPacketInjector
from magma.pipelined.tests.app.start_pipelined import (
- TestSetup,
PipelinedController,
+ TestSetup,
)
-from magma.pipelined.openflow.magma_match import MagmaMatch
-from magma.pipelined.tests.app.flow_query import RyuDirectFlowQuery \
- as FlowQuery
-from magma.pipelined.bridge_util import BridgeTools
from magma.pipelined.tests.pipelined_test_util import (
+ FlowTest,
+ FlowVerifier,
+ SnapshotVerifier,
+ create_service_manager,
start_ryu_app_thread,
stop_ryu_app_thread,
- create_service_manager,
wait_after_send,
- FlowVerifier,
- FlowTest,
- SnapshotVerifier,
)
diff --git a/lte/gateway/python/magma/pipelined/tests/test_ue_passthrough.py b/lte/gateway/python/magma/pipelined/tests/test_ue_passthrough.py
index 3fe8ad1b4340..69b255fa5940 100644
--- a/lte/gateway/python/magma/pipelined/tests/test_ue_passthrough.py
+++ b/lte/gateway/python/magma/pipelined/tests/test_ue_passthrough.py
@@ -15,32 +15,34 @@
from concurrent.futures import Future
from lte.protos.mconfig.mconfigs_pb2 import PipelineD
+from magma.pipelined.app.inout import EGRESS, INGRESS
from magma.pipelined.app.ue_mac import UEMacAddressController
-from magma.pipelined.app.inout import INGRESS, EGRESS
-from magma.pipelined.app.ue_mac import UEMacAddressController
-from magma.pipelined.tests.app.packet_builder import EtherPacketBuilder, \
- UDPPacketBuilder, ARPPacketBuilder, DHCPPacketBuilder
+from magma.pipelined.bridge_util import BridgeTools
+from magma.pipelined.openflow.magma_match import MagmaMatch
+from magma.pipelined.tests.app.flow_query import RyuDirectFlowQuery as FlowQuery
+from magma.pipelined.tests.app.packet_builder import (
+ ARPPacketBuilder,
+ DHCPPacketBuilder,
+ EtherPacketBuilder,
+ UDPPacketBuilder,
+)
from magma.pipelined.tests.app.packet_injector import ScapyPacketInjector
from magma.pipelined.tests.app.start_pipelined import (
- TestSetup,
PipelinedController,
+ TestSetup,
)
-from magma.pipelined.openflow.magma_match import MagmaMatch
-from magma.pipelined.tests.app.flow_query import RyuDirectFlowQuery \
- as FlowQuery
-from ryu.ofproto.ofproto_v1_4 import OFPP_LOCAL
-from magma.pipelined.bridge_util import BridgeTools
from magma.pipelined.tests.pipelined_test_util import (
- start_ryu_app_thread,
- stop_ryu_app_thread,
- create_service_manager,
- wait_after_send,
- FlowVerifier,
FlowTest,
+ FlowVerifier,
SnapshotVerifier,
+ create_service_manager,
fake_inout_setup,
+ start_ryu_app_thread,
+ stop_ryu_app_thread,
+ wait_after_send,
)
from ryu.lib import hub
+from ryu.ofproto.ofproto_v1_4 import OFPP_LOCAL
class UEMacAddressTest(unittest.TestCase):
diff --git a/lte/gateway/python/magma/pipelined/tests/test_uplink_bridge.py b/lte/gateway/python/magma/pipelined/tests/test_uplink_bridge.py
index 3234d3c77efb..b9a930708994 100644
--- a/lte/gateway/python/magma/pipelined/tests/test_uplink_bridge.py
+++ b/lte/gateway/python/magma/pipelined/tests/test_uplink_bridge.py
@@ -10,27 +10,27 @@
See the License for the specific language governing permissions and
limitations under the License.
"""
+import logging
import subprocess
import unittest
import warnings
from concurrent.futures import Future
-import logging
-from ryu.lib import hub
+from magma.pipelined.bridge_util import BridgeTools
from magma.pipelined.tests.app.start_pipelined import (
- TestSetup,
PipelinedController,
+ TestSetup,
)
-from magma.pipelined.bridge_util import BridgeTools
from magma.pipelined.tests.pipelined_test_util import (
- start_ryu_app_thread,
- stop_ryu_app_thread,
- create_service_manager,
assert_bridge_snapshot_match,
- get_ovsdb_port_tag,
- get_iface_ipv4,
+ create_service_manager,
get_iface_gw_ipv4,
+ get_iface_ipv4,
+ get_ovsdb_port_tag,
+ start_ryu_app_thread,
+ stop_ryu_app_thread,
)
+from ryu.lib import hub
class UplinkBridgeTest(unittest.TestCase):
diff --git a/lte/gateway/python/magma/pipelined/tests/test_vlan_learn.py b/lte/gateway/python/magma/pipelined/tests/test_vlan_learn.py
index d95e2c0cce50..8f108bd0fae6 100644
--- a/lte/gateway/python/magma/pipelined/tests/test_vlan_learn.py
+++ b/lte/gateway/python/magma/pipelined/tests/test_vlan_learn.py
@@ -15,19 +15,18 @@
import warnings
from concurrent.futures import Future
-from ryu.lib import hub
-
+from magma.pipelined.bridge_util import BridgeTools
from magma.pipelined.tests.app.start_pipelined import (
- TestSetup,
PipelinedController,
+ TestSetup,
)
-from magma.pipelined.bridge_util import BridgeTools
from magma.pipelined.tests.pipelined_test_util import (
+ assert_bridge_snapshot_match,
+ create_service_manager,
start_ryu_app_thread,
stop_ryu_app_thread,
- create_service_manager,
- assert_bridge_snapshot_match,
)
+from ryu.lib import hub
class VlanLearnTest(unittest.TestCase):
diff --git a/lte/gateway/python/magma/pipelined/tunnel_id_store.py b/lte/gateway/python/magma/pipelined/tunnel_id_store.py
index 1635e8e34e6d..82ae6d06e34a 100644
--- a/lte/gateway/python/magma/pipelined/tunnel_id_store.py
+++ b/lte/gateway/python/magma/pipelined/tunnel_id_store.py
@@ -14,8 +14,10 @@
from magma.common.redis.client import get_default_client
from magma.common.redis.containers import RedisHashDict
-from magma.common.redis.serializers import get_json_deserializer, \
- get_json_serializer
+from magma.common.redis.serializers import (
+ get_json_deserializer,
+ get_json_serializer,
+)
class TunnelToTunnelMapper:
diff --git a/lte/gateway/python/magma/pipelined/utils.py b/lte/gateway/python/magma/pipelined/utils.py
index 8a0fc093309b..7f08baa0edfa 100644
--- a/lte/gateway/python/magma/pipelined/utils.py
+++ b/lte/gateway/python/magma/pipelined/utils.py
@@ -11,10 +11,12 @@
limitations under the License.
"""
import logging
+
from magma.pipelined.openflow import flows
from ryu import cfg
from ryu.lib.ovs import bridge
+
class Utils:
DROP_PRIORITY = flows.MINIMUM_PRIORITY + 1
# For allowing unlcassified flows for app/service type rules.
diff --git a/lte/gateway/python/magma/pkt_tester/tests/test_ovs_gtp.py b/lte/gateway/python/magma/pkt_tester/tests/test_ovs_gtp.py
index 7f90b87765e1..1f2c38a2d050 100644
--- a/lte/gateway/python/magma/pkt_tester/tests/test_ovs_gtp.py
+++ b/lte/gateway/python/magma/pkt_tester/tests/test_ovs_gtp.py
@@ -13,12 +13,11 @@
import unittest
+import test_topology_builder
from nose.plugins.skip import SkipTest
from scapy.all import IP, UDP, L2Socket # pylint: disable=no-name-in-module
from scapy.contrib.gtp import GTPCreatePDPContextRequest, GTPHeader
-import test_topology_builder
-
class TestOvsGtp(unittest.TestCase):
"""
diff --git a/lte/gateway/python/magma/pkt_tester/tests/test_topology_builder.py b/lte/gateway/python/magma/pkt_tester/tests/test_topology_builder.py
index 310740f10799..ef29f6d9003f 100644
--- a/lte/gateway/python/magma/pkt_tester/tests/test_topology_builder.py
+++ b/lte/gateway/python/magma/pkt_tester/tests/test_topology_builder.py
@@ -13,6 +13,7 @@
import os
import unittest
+
from nose.plugins.skip import SkipTest
diff --git a/lte/gateway/python/magma/pkt_tester/topology_builder.py b/lte/gateway/python/magma/pkt_tester/topology_builder.py
index 9767f5dcbe17..ed09f8ea34ec 100644
--- a/lte/gateway/python/magma/pkt_tester/topology_builder.py
+++ b/lte/gateway/python/magma/pkt_tester/topology_builder.py
@@ -11,14 +11,13 @@
limitations under the License.
"""
-import logging
import copy
+import logging
import re
from ovstest import util # pylint: disable=import-error
from ovstest import vswitch # pylint: disable=import-error
-
logger = logging.getLogger(__name__) # pylint: disable=invalid-name
diff --git a/lte/gateway/python/magma/redirectd/main.py b/lte/gateway/python/magma/redirectd/main.py
index 0ae5bec8b5c0..62ae4dcde3aa 100644
--- a/lte/gateway/python/magma/redirectd/main.py
+++ b/lte/gateway/python/magma/redirectd/main.py
@@ -14,11 +14,11 @@
import logging
import threading
-from magma.common.service import MagmaService
+from lte.protos.mconfig import mconfigs_pb2
from magma.common.sentry import sentry_init
+from magma.common.service import MagmaService
from magma.configuration.service_configs import get_service_config_value
from magma.redirectd.redirect_server import run_flask
-from lte.protos.mconfig import mconfigs_pb2
def main():
diff --git a/lte/gateway/python/magma/redirectd/redirect_server.py b/lte/gateway/python/magma/redirectd/redirect_server.py
index 7fafb536f549..a2b369730c4b 100644
--- a/lte/gateway/python/magma/redirectd/redirect_server.py
+++ b/lte/gateway/python/magma/redirectd/redirect_server.py
@@ -14,10 +14,9 @@
import logging
from collections import namedtuple
-from magma.redirectd.redirect_store import RedirectDict
-
import wsgiserver
-from flask import Flask, redirect, request, render_template
+from flask import Flask, redirect, render_template, request
+from magma.redirectd.redirect_store import RedirectDict
""" Use 404 when subscriber not found, 302 for 'Found' redirect """
HTTP_NOT_FOUND = 404
diff --git a/lte/gateway/python/magma/redirectd/redirect_store.py b/lte/gateway/python/magma/redirectd/redirect_store.py
index bb9f5da37113..14af5c61f7a7 100644
--- a/lte/gateway/python/magma/redirectd/redirect_store.py
+++ b/lte/gateway/python/magma/redirectd/redirect_store.py
@@ -12,11 +12,10 @@
"""
from lte.protos.policydb_pb2 import RedirectInformation
-
from magma.common.redis.client import get_default_client
from magma.common.redis.containers import RedisHashDict
-from magma.common.redis.serializers import get_proto_deserializer, \
- get_proto_serializer
+from magma.common.redis.serializers import (get_proto_deserializer,
+ get_proto_serializer)
class RedirectDict(RedisHashDict):
diff --git a/lte/gateway/python/magma/redirectd/tests/test_redirect.py b/lte/gateway/python/magma/redirectd/tests/test_redirect.py
index cab247eb9412..157dc06279a3 100644
--- a/lte/gateway/python/magma/redirectd/tests/test_redirect.py
+++ b/lte/gateway/python/magma/redirectd/tests/test_redirect.py
@@ -15,8 +15,10 @@
from unittest.mock import MagicMock
from lte.protos.policydb_pb2 import RedirectInformation
-from magma.redirectd.redirect_server import HTTP_NOT_FOUND, HTTP_REDIRECT, \
- NOT_FOUND_HTML, RedirectInfo, ServerResponse, setup_flask_server
+from magma.redirectd.redirect_server import (HTTP_NOT_FOUND, HTTP_REDIRECT,
+ NOT_FOUND_HTML, RedirectInfo,
+ ServerResponse,
+ setup_flask_server)
class RedirectdTest(unittest.TestCase):
diff --git a/lte/gateway/python/magma/smsd/main.py b/lte/gateway/python/magma/smsd/main.py
index 146c0658e00b..a74b65cb2313 100644
--- a/lte/gateway/python/magma/smsd/main.py
+++ b/lte/gateway/python/magma/smsd/main.py
@@ -11,13 +11,17 @@
limitations under the License.
"""
+from lte.protos.sms_orc8r_pb2_grpc import (SmsDStub,
+ SMSOrc8rGatewayServiceStub,
+ SMSOrc8rServiceStub)
from magma.common.sentry import sentry_init
from magma.common.service import MagmaService
from magma.common.service_registry import ServiceRegistry
-from lte.protos.sms_orc8r_pb2_grpc import SMSOrc8rServiceStub, SMSOrc8rGatewayServiceStub, SmsDStub
from orc8r.protos.directoryd_pb2_grpc import GatewayDirectoryServiceStub
+
from .relay import SmsRelay
+
def main():
""" main() for smsd """
service = MagmaService('smsd', None)
diff --git a/lte/gateway/python/magma/smsd/relay.py b/lte/gateway/python/magma/smsd/relay.py
index 33857b24ae82..17cc0e796cc2 100644
--- a/lte/gateway/python/magma/smsd/relay.py
+++ b/lte/gateway/python/magma/smsd/relay.py
@@ -15,13 +15,12 @@
from typing import List
import grpc
+import lte.protos.sms_orc8r_pb2 as sms_orc8r_pb2
+import lte.protos.sms_orc8r_pb2_grpc as sms_orc8r_pb2_grpc
+from lte.protos.mconfig.mconfigs_pb2 import MME
from magma.common.job import Job
-
from magma.common.rpc_utils import grpc_async_wrapper, return_void
from magma.configuration.mconfig_managers import load_service_mconfig
-from lte.protos.mconfig.mconfigs_pb2 import MME
-import lte.protos.sms_orc8r_pb2_grpc as sms_orc8r_pb2_grpc
-import lte.protos.sms_orc8r_pb2 as sms_orc8r_pb2
from orc8r.protos.common_pb2 import Void
from orc8r.protos.directoryd_pb2_grpc import GatewayDirectoryServiceStub
diff --git a/lte/gateway/python/scripts/agw_health_cli.py b/lte/gateway/python/scripts/agw_health_cli.py
index 6e8076f59158..22bd65538c58 100644
--- a/lte/gateway/python/scripts/agw_health_cli.py
+++ b/lte/gateway/python/scripts/agw_health_cli.py
@@ -12,10 +12,10 @@
See the License for the specific language governing permissions and
limitations under the License.
"""
+import math
import subprocess
import fire
-import math
from magma.health.health_service import AGWHealth
from termcolor import colored
diff --git a/lte/gateway/python/scripts/config_stateless_agw.py b/lte/gateway/python/scripts/config_stateless_agw.py
index 9f3d9e1ad1da..6df1ef63da92 100755
--- a/lte/gateway/python/scripts/config_stateless_agw.py
+++ b/lte/gateway/python/scripts/config_stateless_agw.py
@@ -17,19 +17,16 @@
import argparse
import os
+import shlex
import subprocess
import sys
-import shlex
import time
-
from enum import Enum
from magma.common.redis.client import get_default_client
-from magma.configuration.service_configs import (
- load_override_config,
- load_service_config,
- save_override_config,
-)
+from magma.configuration.service_configs import (load_override_config,
+ load_service_config,
+ save_override_config)
return_codes = Enum(
"return_codes", "STATELESS STATEFUL CORRUPT INVALID", start=0
@@ -158,6 +155,14 @@ def disable_stateless_agw():
sys.exit(check_stateless_services().value)
+def ovs_reset_bridges():
+ subprocess.call("ifdown uplink_br0".split())
+ subprocess.call("ifdown gtp_br0".split())
+ subprocess.call("service openvswitch-switch restart".split())
+ subprocess.call("ifup uplink_br0".split())
+ subprocess.call("ifup gtp_br0".split())
+
+
def sctpd_pre_start():
if check_stateless_services() == return_codes.STATEFUL:
# switching from stateless to stateful
@@ -166,8 +171,7 @@ def sctpd_pre_start():
# Clean up all mobilityd, MME, pipelined and sessiond Redis keys
clear_redis_state()
# Clean up OVS flows
- subprocess.call("service openvswitch-switch restart".split())
-
+ ovs_reset_bridges()
sys.exit(0)
diff --git a/lte/gateway/python/scripts/cpe_monitoring_cli.py b/lte/gateway/python/scripts/cpe_monitoring_cli.py
index 45bfe1a718ad..40a45e8c7f80 100755
--- a/lte/gateway/python/scripts/cpe_monitoring_cli.py
+++ b/lte/gateway/python/scripts/cpe_monitoring_cli.py
@@ -11,6 +11,9 @@
limitations under the License.
"""
import ipaddress
+import re
+import subprocess
+from datetime import datetime
from time import sleep
import fire
@@ -18,10 +21,6 @@
from magma.common.service_registry import ServiceRegistry
from orc8r.protos.common_pb2 import Void
-import subprocess
-import re
-from datetime import datetime
-
class MonitoringCLI(object):
"""
diff --git a/lte/gateway/python/scripts/create_oai_certs.py b/lte/gateway/python/scripts/create_oai_certs.py
index 2da3f2778cf5..4fc262427082 100755
--- a/lte/gateway/python/scripts/create_oai_certs.py
+++ b/lte/gateway/python/scripts/create_oai_certs.py
@@ -14,12 +14,13 @@
"""
import argparse
-import envoy
import os
import shutil
import socket
import tempfile
+import envoy
+
OPENSSL_BIN = "/usr/bin/openssl"
# Default mme/freediameter (s6a) cert and key file names.
diff --git a/lte/gateway/python/scripts/dp_probe_cli.py b/lte/gateway/python/scripts/dp_probe_cli.py
index 4359d4161b37..03695751a4ad 100644
--- a/lte/gateway/python/scripts/dp_probe_cli.py
+++ b/lte/gateway/python/scripts/dp_probe_cli.py
@@ -20,6 +20,7 @@
from lte.protos.mconfig import mconfigs_pb2
from magma.common.service import MagmaService
+
def create_parser():
"""
Creates the argparse parser with all the arguments.
@@ -29,11 +30,32 @@ def create_parser():
"To display the Datapath actions of the supplied IMSI",
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
- parser.add_argument("-i", "--imsi", help="IMSI of the subscriber")
- parser.add_argument("-I", "--ip", help="External IP")
- parser.add_argument("-P", "--port", help="External Port")
- parser.add_argument("-UP", "--ue_port", help="UE Port")
- parser.add_argument("-p", "--protocol", help="Portocol (i.e. tcp, udp, icmp)")
+ parser.add_argument("-i", "--imsi", required=True, help="IMSI of the subscriber")
+ parser.add_argument(
+ "-d",
+ "--direction",
+ required=True,
+ choices=["DL", "UL"],
+ help="Direction - DL/UL",
+ )
+ parser.add_argument(
+ "-I", "--ip", nargs="?", const="8.8.8.8", default="8.8.8.8", help="External IP"
+ )
+ parser.add_argument(
+ "-P", "--port", nargs="?", const="80", default="80", help="External Port"
+ )
+ parser.add_argument(
+ "-UP", "--ue_port", nargs="?", const="3372", default="3372", help="UE Port"
+ )
+ parser.add_argument(
+ "-p",
+ "--protocol",
+ choices=["tcp", "udp", "icmp"],
+ nargs="?",
+ const="tcp",
+ default="tcp",
+ help="Portocol (i.e. tcp, udp, icmp)",
+ )
return parser
@@ -49,41 +71,92 @@ def find_ue_ip(imsi: str):
match = re.search(pattern, output_str)
if match:
return match.group(1)
- else:
- return "NA"
+ return
def output_datapath_actions(
- ue_ip: str, external_ip: str, external_port: str, ue_port: str, protocol: str
+ imsi: str,
+ direction: str,
+ ue_ip: str,
+ external_ip: str,
+ external_port: str,
+ ue_port: str,
+ protocol: str,
):
"""
Returns the Output of Datapath Actions based as per the supplied UE IP
"""
service = MagmaService("pipelined", mconfigs_pb2.PipelineD())
+ cmd = ["sudo", "ovs-appctl", "ofproto/trace", "gtp_br0"]
if service.mconfig.nat_enabled:
in_port = "local"
else:
in_port = "patch-up"
- cmd = ["sudo", "ovs-appctl", "ofproto/trace", "gtp_br0"]
+ if direction == "DL":
- cmd_append = (
- protocol + ",in_port=" + in_port + ",ip_dst=" + ue_ip + ",ip_src=" + external_ip
- )
+ cmd_append = (
+ protocol
+ + ",in_port="
+ + in_port
+ + ",ip_dst="
+ + ue_ip
+ + ",ip_src="
+ + external_ip
+ )
- if protocol != "icmp":
- cmd_append += (
- ","
- + protocol
- + "_src="
- + external_port
- + ","
- + protocol
- + "_dst="
- + ue_port
+ if protocol != "icmp":
+ cmd_append += (
+ ","
+ + protocol
+ + "_src="
+ + external_port
+ + ","
+ + protocol
+ + "_dst="
+ + ue_port
+ )
+
+ cmd.append(cmd_append)
+
+ elif direction == "UL":
+ ingress_tun_id = get_ingress_tunid(ue_ip, in_port)
+ if not ingress_tun_id:
+ print("Ingress Tunnel not Found")
+ exit(1)
+
+ data = get_egress_tunid_and_port(ue_ip, ingress_tun_id)
+ if not data:
+ print("Egress Tunnel not Found")
+ exit(1)
+
+ cmd_append = (
+ protocol
+ + ",in_port="
+ + data["in_port"]
+ + ",tun_id="
+ + data["tun_id"]
+ + ",ip_dst="
+ + external_ip
+ + ",ip_src="
+ + ue_ip
)
- cmd.append(cmd_append)
+ if protocol != "icmp":
+ cmd_append += (
+ ","
+ + protocol
+ + "_src="
+ + ue_port
+ + ","
+ + protocol
+ + "_dst="
+ + external_port
+ )
+
+ cmd.append(cmd_append)
+ else:
+ return
print("Running: " + " ".join(cmd))
output = subprocess.check_output(cmd)
@@ -93,45 +166,60 @@ def output_datapath_actions(
if match:
return match.group(1).strip()
else:
- return "NA"
-
-
-def get_options(args):
- external_ip = args.ip if args.ip else "8.8.8.8"
- external_port = args.port if args.port else "80"
- ue_port = args.ue_port if args.ue_port else "3372"
- protocol = args.protocol if args.protocol else "tcp"
+ return
- return {
- "external_ip": external_ip,
- "external_port": external_port,
- "ue_port": ue_port,
- "protocol": protocol,
- }
+def get_ingress_tunid(ue_ip: str, in_port: str):
+ cmd = ["sudo", "ovs-ofctl", "dump-flows", "gtp_br0", "table=0"]
+ output = subprocess.check_output(cmd)
+ output = str(output, "utf-8").strip()
+ pattern = (
+ ".*?in_port="
+ + in_port
+ + ",nw_dst="
+ + ue_ip
+ + ".*?load:(0x(?:[a-z]|[0-9]){1,})->OXM_OF_METADATA.*?"
+ )
+ match = re.findall(pattern, output, re.IGNORECASE)
+ if match:
+ return match[0]
+ return
+def get_egress_tunid_and_port(ue_ip: str, ingress_tun: str):
+ cmd = ["sudo", "ovs-ofctl", "dump-flows", "gtp_br0", "table=0"]
+ output = subprocess.check_output(cmd)
+ output = str(output, "utf-8").strip()
+ pattern = pattern = (
+ "tun_id=(0x(?:[a-z]|[0-9]){1,}),in_port=([a-z]|[0-9]).*?load:"
+ + ingress_tun
+ + "->OXM_OF_METADATA.*?\n"
+ )
+ match = re.findall(pattern, output)
+ if match:
+ return {"tun_id": match[0][0], "in_port": match[0][1]}
+ return
def main():
parser = create_parser()
# Parse the args
args = parser.parse_args()
- if not args.imsi:
- parser.print_usage()
- exit(1)
ue_ip = find_ue_ip(args.imsi)
- if ue_ip == "NA":
+ if not ue_ip:
print("UE is not connected")
exit(1)
print("IMSI: " + args.imsi + ", IP: " + ue_ip)
- input_options = get_options(args)
dp_actions = output_datapath_actions(
+ args.imsi,
+ args.direction,
ue_ip,
- input_options["external_ip"],
- input_options["external_port"],
- input_options["ue_port"],
- input_options["protocol"],
+ args.ip,
+ args.port,
+ args.ue_port,
+ args.protocol,
)
+ if not dp_actions:
+ print("Cannot find Datapath Actions for the UE")
print("Datapath Actions: " + dp_actions)
diff --git a/lte/gateway/python/scripts/enodebd_cli.py b/lte/gateway/python/scripts/enodebd_cli.py
index 8501db901b4e..dcb7992002cf 100755
--- a/lte/gateway/python/scripts/enodebd_cli.py
+++ b/lte/gateway/python/scripts/enodebd_cli.py
@@ -14,10 +14,11 @@
"""
import argparse
-from magma.common.rpc_utils import grpc_wrapper
-from lte.protos.enodebd_pb2 import GetParameterRequest, SetParameterRequest, \
- EnodebIdentity, SingleEnodebStatus
+
+from lte.protos.enodebd_pb2 import (EnodebIdentity, GetParameterRequest,
+ SetParameterRequest, SingleEnodebStatus)
from lte.protos.enodebd_pb2_grpc import EnodebdStub
+from magma.common.rpc_utils import grpc_wrapper
from orc8r.protos.common_pb2 import Void
diff --git a/lte/gateway/python/scripts/fake_user.py b/lte/gateway/python/scripts/fake_user.py
index cacbe1678a2b..b2d587b9c735 100755
--- a/lte/gateway/python/scripts/fake_user.py
+++ b/lte/gateway/python/scripts/fake_user.py
@@ -13,16 +13,16 @@
"""
import argparse
-import netifaces
import os
import sys
+import netifaces
+from lte.protos.session_manager_pb2 import LocalCreateSessionRequest
+from lte.protos.session_manager_pb2_grpc import LocalSessionManagerStub
from magma.common.service_registry import ServiceRegistry
-from magma.subscriberdb.sid import SIDUtils
from magma.configuration import environment
from magma.pipelined.imsi import encode_imsi
-from lte.protos.session_manager_pb2 import LocalCreateSessionRequest
-from lte.protos.session_manager_pb2_grpc import LocalSessionManagerStub
+from magma.subscriberdb.sid import SIDUtils
def sample_commands():
diff --git a/lte/gateway/python/scripts/feg_hello_cli.py b/lte/gateway/python/scripts/feg_hello_cli.py
index ab8d1d8d9ae0..7447f18bec14 100755
--- a/lte/gateway/python/scripts/feg_hello_cli.py
+++ b/lte/gateway/python/scripts/feg_hello_cli.py
@@ -15,9 +15,9 @@
import argparse
-from magma.common.rpc_utils import cloud_grpc_wrapper
from feg.protos.hello_pb2 import HelloRequest
from feg.protos.hello_pb2_grpc import HelloStub
+from magma.common.rpc_utils import cloud_grpc_wrapper
@cloud_grpc_wrapper
diff --git a/lte/gateway/python/scripts/generate_dnsd_config.py b/lte/gateway/python/scripts/generate_dnsd_config.py
index d8acd57d2dba..f673e9114600 100755
--- a/lte/gateway/python/scripts/generate_dnsd_config.py
+++ b/lte/gateway/python/scripts/generate_dnsd_config.py
@@ -17,11 +17,11 @@
import logging
from generate_service_config import generate_template_config
+from lte.protos.mconfig.mconfigs_pb2 import DnsD
from magma.common.misc_utils import get_ip_from_if_cidr
from magma.configuration.exceptions import LoadConfigError
from magma.configuration.mconfig_managers import load_service_mconfig
from magma.configuration.service_configs import load_service_config
-from lte.protos.mconfig.mconfigs_pb2 import DnsD
CONFIG_OVERRIDE_DIR = '/var/opt/magma/tmp'
diff --git a/lte/gateway/python/scripts/generate_oai_config.py b/lte/gateway/python/scripts/generate_oai_config.py
index ca3018b66316..893766673e2c 100755
--- a/lte/gateway/python/scripts/generate_oai_config.py
+++ b/lte/gateway/python/scripts/generate_oai_config.py
@@ -177,18 +177,29 @@ def _get_apn_correction_map_list(service_mconfig):
return service_mconfig.apn_correction_map_list
return get_service_config_value("mme", "apn_correction_map_list", None)
+
def _get_federated_mode_map(service_mconfig):
- if service_mconfig.federated_mode_map and \
- service_mconfig.federated_mode_map.enabled and \
- len(service_mconfig.federated_mode_map.mapping) != 0:
+ if (
+ service_mconfig.federated_mode_map
+ and service_mconfig.federated_mode_map.enabled
+ and len(service_mconfig.federated_mode_map.mapping) != 0
+ ):
return service_mconfig.federated_mode_map.mapping
return {}
+
def _get_restricted_plmns(service_mconfig):
if service_mconfig.restricted_plmns:
return service_mconfig.restricted_plmns
return {}
+
+def _get_restricted_imeis(service_mconfig):
+ if service_mconfig.restricted_imeis:
+ return service_mconfig.restricted_imeis
+ return {}
+
+
def _get_context():
"""
Create the context which has the interface IP and the OAI log level to use.
@@ -199,64 +210,61 @@ def _get_context():
"mme_s11_ip": _get_iface_ip("mme", "s11_iface_name"),
"sgw_s11_ip": _get_iface_ip("spgw", "s11_iface_name"),
"sgw_s5s8_up_ip": _get_iface_ip("spgw", "sgw_s5s8_up_iface_name"),
- "remote_sgw_ip": get_service_config_value("mme",
- "remote_sgw_ip", ""),
+ "remote_sgw_ip": get_service_config_value("mme", "remote_sgw_ip", ""),
"s1ap_ip": _get_iface_ip("mme", "s1ap_iface_name"),
"oai_log_level": _get_oai_log_level(),
- "ipv4_dns": _get_primary_dns_ip(mme_service_config,
- 'dns_iface_name'),
+ "ipv4_dns": _get_primary_dns_ip(mme_service_config, "dns_iface_name"),
"ipv4_sec_dns": _get_secondary_dns_ip(mme_service_config),
"ipv4_p_cscf_address": _get_ipv4_pcscf_ip(mme_service_config),
"ipv6_dns": _get_ipv6_dns_ip(mme_service_config),
"ipv6_p_cscf_address": _get_ipv6_pcscf_ip(mme_service_config),
"identity": _get_identity(),
"relay_enabled": _get_relay_enabled(mme_service_config),
- "non_eps_service_control": _get_non_eps_service_control(
- mme_service_config),
+ "non_eps_service_control": _get_non_eps_service_control(mme_service_config),
"csfb_mcc": _get_csfb_mcc(mme_service_config),
"csfb_mnc": _get_csfb_mnc(mme_service_config),
"lac": _get_lac(mme_service_config),
- "use_stateless": get_service_config_value("mme",
- "use_stateless", ""),
+ "use_stateless": get_service_config_value("mme", "use_stateless", ""),
"attached_enodeb_tacs": _get_attached_enodeb_tacs(mme_service_config),
"enable_nat": _get_enable_nat(mme_service_config),
- "federated_mode_map" : _get_federated_mode_map(mme_service_config),
- "restricted_plmns" : _get_restricted_plmns(mme_service_config)
+ "federated_mode_map": _get_federated_mode_map(mme_service_config),
+ "restricted_plmns": _get_restricted_plmns(mme_service_config),
+ "restricted_imeis": _get_restricted_imeis(mme_service_config),
}
- context["s1u_ip"] = mme_service_config.ipv4_sgw_s1u_addr or \
- _get_iface_ip("spgw", "s1u_iface_name")
+ context["s1u_ip"] = mme_service_config.ipv4_sgw_s1u_addr or _get_iface_ip(
+ "spgw", "s1u_iface_name"
+ )
# set ovs params
for key in (
- "ovs_bridge_name",
- "ovs_gtp_port_number",
- "ovs_mtr_port_number",
- "ovs_internal_sampling_port_number",
- "ovs_internal_sampling_fwd_tbl",
- "ovs_uplink_port_number",
- "ovs_uplink_mac",
+ "ovs_bridge_name",
+ "ovs_gtp_port_number",
+ "ovs_mtr_port_number",
+ "ovs_internal_sampling_port_number",
+ "ovs_internal_sampling_fwd_tbl",
+ "ovs_uplink_port_number",
+ "ovs_uplink_mac",
):
context[key] = get_service_config_value("spgw", key, "")
- context["enable_apn_correction"] = \
- get_service_config_value("mme", "enable_apn_correction", "")
- context["apn_correction_map_list"] = \
- _get_apn_correction_map_list(mme_service_config)
+ context["enable_apn_correction"] = get_service_config_value(
+ "mme", "enable_apn_correction", ""
+ )
+ context["apn_correction_map_list"] = _get_apn_correction_map_list(
+ mme_service_config
+ )
return context
def main():
logging.basicConfig(
- level=logging.INFO,
- format="[%(asctime)s %(levelname)s %(name)s] %(message)s"
+ level=logging.INFO, format="[%(asctime)s %(levelname)s %(name)s] %(message)s"
)
context = _get_context()
- generate_template_config("spgw", "spgw", CONFIG_OVERRIDE_DIR,
- context.copy())
+ generate_template_config("spgw", "spgw", CONFIG_OVERRIDE_DIR, context.copy())
generate_template_config("mme", "mme", CONFIG_OVERRIDE_DIR, context.copy())
- generate_template_config("mme", "mme_fd", CONFIG_OVERRIDE_DIR,
- context.copy())
+ generate_template_config("mme", "mme_fd", CONFIG_OVERRIDE_DIR, context.copy())
cert_dir = get_service_config_value("mme", "cert_dir", "")
generate_mme_certs(os.path.join(cert_dir, "freeDiameter"))
diff --git a/lte/gateway/python/scripts/ha_cli.py b/lte/gateway/python/scripts/ha_cli.py
index a6070588f409..55c55656dfed 100644
--- a/lte/gateway/python/scripts/ha_cli.py
+++ b/lte/gateway/python/scripts/ha_cli.py
@@ -14,14 +14,12 @@
"""
import argparse
-import grpc
-from magma.common.rpc_utils import grpc_wrapper
-from lte.protos.ha_service_pb2 import (
- StartAgwOffloadRequest,
- StartAgwOffloadResponse
-)
+import grpc
+from lte.protos.ha_service_pb2 import StartAgwOffloadRequest
from lte.protos.ha_service_pb2_grpc import HaServiceStub
+from magma.common.rpc_utils import grpc_wrapper
+
@grpc_wrapper
def send_offload_trigger(client, args):
diff --git a/lte/gateway/python/scripts/hello_cli.py b/lte/gateway/python/scripts/hello_cli.py
index d4700a6a8bae..e298c1300bd8 100755
--- a/lte/gateway/python/scripts/hello_cli.py
+++ b/lte/gateway/python/scripts/hello_cli.py
@@ -13,9 +13,9 @@
limitations under the License.
"""
-from magma.common.rpc_utils import grpc_wrapper
from feg.protos.hello_pb2 import HelloRequest
from feg.protos.hello_pb2_grpc import HelloStub
+from magma.common.rpc_utils import grpc_wrapper
@grpc_wrapper
diff --git a/lte/gateway/python/scripts/mobility_cli.py b/lte/gateway/python/scripts/mobility_cli.py
index dc48dee2a64c..a519c26dcd2e 100755
--- a/lte/gateway/python/scripts/mobility_cli.py
+++ b/lte/gateway/python/scripts/mobility_cli.py
@@ -17,12 +17,13 @@
import ipaddress
import sys
+from lte.protos.mobilityd_pb2 import (AllocateIPRequest, GWInfo, IPAddress,
+ IPBlock, ReleaseIPRequest,
+ RemoveIPBlockRequest)
+from lte.protos.mobilityd_pb2_grpc import MobilityServiceStub
from magma.common.rpc_utils import grpc_wrapper
from magma.subscriberdb.sid import SIDUtils
from orc8r.protos.common_pb2 import Void
-from lte.protos.mobilityd_pb2 import AllocateIPRequest, \
- IPAddress, IPBlock, ReleaseIPRequest, RemoveIPBlockRequest, GWInfo
-from lte.protos.mobilityd_pb2_grpc import MobilityServiceStub
@grpc_wrapper
diff --git a/lte/gateway/python/scripts/mobility_dhcp_cli.py b/lte/gateway/python/scripts/mobility_dhcp_cli.py
index 3a7943abb654..fdd952366bf1 100755
--- a/lte/gateway/python/scripts/mobility_dhcp_cli.py
+++ b/lte/gateway/python/scripts/mobility_dhcp_cli.py
@@ -19,12 +19,12 @@
import argparse
import ipaddress
-from ipaddress import ip_address, ip_network
import random
import sys
+from ipaddress import ip_address, ip_network
from magma.mobilityd import mobility_store as store
-from magma.mobilityd.dhcp_desc import DHCPState, DHCPDescriptor
+from magma.mobilityd.dhcp_desc import DHCPDescriptor, DHCPState
from magma.mobilityd.mac import MacAddress
from magma.mobilityd.uplink_gw import UplinkGatewayInfo
diff --git a/lte/gateway/python/scripts/ocs_cli.py b/lte/gateway/python/scripts/ocs_cli.py
index ad76b9810523..38c5c821fe2a 100755
--- a/lte/gateway/python/scripts/ocs_cli.py
+++ b/lte/gateway/python/scripts/ocs_cli.py
@@ -14,11 +14,11 @@
"""
import argparse
-import grpc
+import grpc
+from feg.protos.mock_core_pb2_grpc import MockCoreConfiguratorStub
from magma.common.rpc_utils import cloud_grpc_wrapper
from orc8r.protos.common_pb2 import Void
-from feg.protos.mock_core_pb2_grpc import MockCoreConfiguratorStub
@cloud_grpc_wrapper
diff --git a/lte/gateway/python/scripts/packet_ryu_cli.py b/lte/gateway/python/scripts/packet_ryu_cli.py
index e9ea02844c17..09196b74583b 100755
--- a/lte/gateway/python/scripts/packet_ryu_cli.py
+++ b/lte/gateway/python/scripts/packet_ryu_cli.py
@@ -13,13 +13,15 @@
limitations under the License.
"""
-import logging
import argparse
+import logging
+
+from integ_tests.s1aptests.ovs.rest_api import (add_flowentry,
+ delete_flowentry, get_datapath,
+ get_flows)
+from scapy.all import IP, Ether, sendp
-from integ_tests.s1aptests.ovs.rest_api import get_datapath, get_flows,\
- delete_flowentry, add_flowentry
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
-from scapy.all import Ether, IP, sendp
DEFAULT_PKT_MAC_SRC = "00:00:00:00:00:01"
DEFAULT_PKT_MAC_DST = "12:99:cc:97:47:4e"
diff --git a/lte/gateway/python/scripts/packet_tracer_cli.py b/lte/gateway/python/scripts/packet_tracer_cli.py
index c514d50ad79e..f384ae0d8261 100755
--- a/lte/gateway/python/scripts/packet_tracer_cli.py
+++ b/lte/gateway/python/scripts/packet_tracer_cli.py
@@ -13,8 +13,8 @@
limitations under the License.
"""
-import subprocess
import argparse
+import subprocess
from magma.configuration.service_configs import load_service_config
diff --git a/lte/gateway/python/scripts/pcrf_cli.py b/lte/gateway/python/scripts/pcrf_cli.py
index 0c6b13f72fb3..ebe05ef5501e 100755
--- a/lte/gateway/python/scripts/pcrf_cli.py
+++ b/lte/gateway/python/scripts/pcrf_cli.py
@@ -14,11 +14,11 @@
"""
import argparse
-import grpc
+import grpc
+from feg.protos.mock_core_pb2_grpc import MockCoreConfiguratorStub
from magma.common.rpc_utils import cloud_grpc_wrapper
from orc8r.protos.common_pb2 import Void
-from feg.protos.mock_core_pb2_grpc import MockCoreConfiguratorStub
@cloud_grpc_wrapper
diff --git a/lte/gateway/python/scripts/pipelined_cli.py b/lte/gateway/python/scripts/pipelined_cli.py
index eb671f61c395..baacc94a0d3a 100755
--- a/lte/gateway/python/scripts/pipelined_cli.py
+++ b/lte/gateway/python/scripts/pipelined_cli.py
@@ -15,44 +15,35 @@
import argparse
import errno
-import time
import random
import subprocess
-from datetime import datetime
+import time
from collections import namedtuple
+from datetime import datetime
from pprint import pprint
-from magma.common.rpc_utils import grpc_wrapper, grpc_async_wrapper
-from lte.protos.pipelined_pb2 import (
- SubscriberQuotaUpdate,
- UpdateSubscriberQuotaStateRequest,
-)
-from lte.protos.policydb_pb2 import RedirectInformation
+from lte.protos.pipelined_pb2 import (ActivateFlowsRequest,
+ DeactivateFlowsRequest,
+ DeactivateFlowsResult, RequestOriginType,
+ RuleModResult, SubscriberQuotaUpdate,
+ UEMacFlowRequest,
+ UpdateSubscriberQuotaStateRequest)
+from lte.protos.pipelined_pb2_grpc import PipelinedStub
+from lte.protos.policydb_pb2 import (FlowDescription, FlowMatch, PolicyRule,
+ RedirectInformation)
+from lte.protos.subscriberdb_pb2 import AggregatedMaximumBitrate
+from magma.common.rpc_utils import grpc_wrapper
+from magma.configuration.service_configs import load_service_config
from magma.pipelined.app.enforcement import EnforcementController
from magma.pipelined.app.enforcement_stats import EnforcementStatsController
-from magma.pipelined.policy_converters import convert_ipv4_str_to_ip_proto
-from magma.subscriberdb.sid import SIDUtils
-from magma.configuration.service_configs import load_service_config
from magma.pipelined.bridge_util import BridgeTools
-from magma.pipelined.service_manager import Tables
+from magma.pipelined.policy_converters import convert_ipv4_str_to_ip_proto
from magma.pipelined.qos.common import QosManager
+from magma.pipelined.service_manager import Tables
+from magma.pipelined.tests.app.ng_set_session_msg import CreateSessionUtil
+from magma.subscriberdb.sid import SIDUtils
from orc8r.protos.common_pb2 import Void
-from lte.protos.pipelined_pb2 import (
- ActivateFlowsRequest,
- DeactivateFlowsRequest,
- RuleModResult,
- UEMacFlowRequest,
- RequestOriginType,
- DeactivateFlowsResult,
-)
-from lte.protos.subscriberdb_pb2 import (
- AggregatedMaximumBitrate,
-)
-from magma.pipelined.tests.app.ng_set_session_msg import (
- CreateSessionUtil)
-from lte.protos.pipelined_pb2_grpc import PipelinedStub
-from lte.protos.policydb_pb2 import FlowMatch, FlowDescription, PolicyRule
@grpc_wrapper
def set_smf_session(client, args):
diff --git a/lte/gateway/python/scripts/policydb_cli.py b/lte/gateway/python/scripts/policydb_cli.py
index d53d4faa4855..f63ccc0b80b8 100755
--- a/lte/gateway/python/scripts/policydb_cli.py
+++ b/lte/gateway/python/scripts/policydb_cli.py
@@ -14,15 +14,16 @@
"""
import argparse
+
import grpc
-from lte.protos.policydb_pb2 import FlowMatch, FlowDescription, PolicyRule, \
- EnableStaticRuleRequest, DisableStaticRuleRequest
from lte.protos.mobilityd_pb2 import IPAddress
+from lte.protos.policydb_pb2 import (DisableStaticRuleRequest,
+ EnableStaticRuleRequest, FlowDescription,
+ FlowMatch, PolicyRule)
from lte.protos.policydb_pb2_grpc import PolicyDBStub
from magma.common.rpc_utils import grpc_wrapper
from magma.policydb.rule_store import PolicyRuleDict
-
DEBUG_MSG = 'You may want to check that a connection can be made to ' \
'orc8r to update the assignments of rules/basenames to ' \
'the subscriber.'
diff --git a/lte/gateway/python/scripts/s6a_proxy_cli.py b/lte/gateway/python/scripts/s6a_proxy_cli.py
index 6868c33c7628..f32f836e7562 100755
--- a/lte/gateway/python/scripts/s6a_proxy_cli.py
+++ b/lte/gateway/python/scripts/s6a_proxy_cli.py
@@ -16,10 +16,9 @@
import argparse
import grpc
-from feg.protos.s6a_proxy_pb2 import AuthenticationInformationRequest, \
- UpdateLocationRequest
+from feg.protos.s6a_proxy_pb2 import (AuthenticationInformationRequest,
+ UpdateLocationRequest)
from feg.protos.s6a_proxy_pb2_grpc import S6aProxyStub
-
from magma.common.rpc_utils import cloud_grpc_wrapper
RESYNC_INFO_BYTES = 30
diff --git a/lte/gateway/python/scripts/s6a_service_cli.py b/lte/gateway/python/scripts/s6a_service_cli.py
index 7dd1fa5b89a5..fbfbeb534916 100755
--- a/lte/gateway/python/scripts/s6a_service_cli.py
+++ b/lte/gateway/python/scripts/s6a_service_cli.py
@@ -15,9 +15,9 @@
import argparse
-from magma.common.rpc_utils import grpc_wrapper
from lte.protos.s6a_service_pb2 import DeleteSubscriberRequest
from lte.protos.s6a_service_pb2_grpc import S6aServiceStub
+from magma.common.rpc_utils import grpc_wrapper
@grpc_wrapper
diff --git a/lte/gateway/python/scripts/session_manager_cli.py b/lte/gateway/python/scripts/session_manager_cli.py
index 45aae150daa3..6cf3f6d69e6c 100755
--- a/lte/gateway/python/scripts/session_manager_cli.py
+++ b/lte/gateway/python/scripts/session_manager_cli.py
@@ -17,29 +17,16 @@
import grpc
from feg.protos.mock_core_pb2_grpc import MockOCSStub, MockPCRFStub
-from lte.protos.policydb_pb2 import (
- FlowDescription,
- FlowMatch,
- FlowQos,
- PolicyRule,
- QosArp,
-)
-from lte.protos.session_manager_pb2 import (
- DynamicRuleInstall,
- LocalCreateSessionRequest,
- PolicyReAuthRequest,
- QoSInformation,
-)
-from lte.protos.session_manager_pb2_grpc import (
- LocalSessionManagerStub,
- SessionProxyResponderStub,
-)
-from lte.protos.abort_session_pb2 import (
- AbortSessionRequest,
-)
-from lte.protos.abort_session_pb2_grpc import (
- AbortSessionResponderStub,
-)
+from lte.protos.abort_session_pb2 import AbortSessionRequest
+from lte.protos.abort_session_pb2_grpc import AbortSessionResponderStub
+from lte.protos.policydb_pb2 import (FlowDescription, FlowMatch, FlowQos,
+ PolicyRule, QosArp)
+from lte.protos.session_manager_pb2 import (DynamicRuleInstall,
+ LocalCreateSessionRequest,
+ PolicyReAuthRequest,
+ QoSInformation)
+from lte.protos.session_manager_pb2_grpc import (LocalSessionManagerStub,
+ SessionProxyResponderStub)
from lte.protos.subscriberdb_pb2 import SubscriberID
from magma.common.rpc_utils import grpc_wrapper
from magma.common.service_registry import ServiceRegistry
@@ -303,4 +290,4 @@ def main():
if __name__ == "__main__":
- main()
\ No newline at end of file
+ main()
diff --git a/lte/gateway/python/scripts/sgs_cli.py b/lte/gateway/python/scripts/sgs_cli.py
index 97aa98e22529..a3f8ac542b21 100755
--- a/lte/gateway/python/scripts/sgs_cli.py
+++ b/lte/gateway/python/scripts/sgs_cli.py
@@ -14,12 +14,12 @@
"""
import argparse
-import grpc
-from magma.common.rpc_utils import cloud_grpc_wrapper
-from feg.protos.csfb_pb2 import AlertAck, AlertReject, EPSDetachIndication, \
- IMSIDetachIndication
+import grpc
+from feg.protos.csfb_pb2 import (AlertAck, AlertReject, EPSDetachIndication,
+ IMSIDetachIndication)
from feg.protos.csfb_pb2_grpc import CSFBFedGWServiceStub
+from magma.common.rpc_utils import cloud_grpc_wrapper
@cloud_grpc_wrapper
diff --git a/lte/gateway/python/scripts/sms_cli.py b/lte/gateway/python/scripts/sms_cli.py
index 4477f7b2cf4e..c4584e4a089a 100755
--- a/lte/gateway/python/scripts/sms_cli.py
+++ b/lte/gateway/python/scripts/sms_cli.py
@@ -14,11 +14,12 @@
"""
import argparse
-import grpc
-from magma.common.rpc_utils import grpc_wrapper
+import grpc
from lte.protos.sms_orc8r_pb2 import SMODownlinkUnitdata
from lte.protos.sms_orc8r_pb2_grpc import SMSOrc8rGatewayServiceStub
+from magma.common.rpc_utils import grpc_wrapper
+
@grpc_wrapper
def send_downlink_unitdata(client, args):
diff --git a/lte/gateway/python/scripts/spgw_service_cli.py b/lte/gateway/python/scripts/spgw_service_cli.py
index 01f27baca446..212341335bc8 100755
--- a/lte/gateway/python/scripts/spgw_service_cli.py
+++ b/lte/gateway/python/scripts/spgw_service_cli.py
@@ -15,11 +15,11 @@
import argparse
-from magma.common.rpc_utils import grpc_wrapper
-from lte.protos.spgw_service_pb2 import CreateBearerRequest, \
- DeleteBearerRequest
+from lte.protos.policydb_pb2 import FlowQos, PolicyRule, QosArp
+from lte.protos.spgw_service_pb2 import (CreateBearerRequest,
+ DeleteBearerRequest)
from lte.protos.spgw_service_pb2_grpc import SpgwServiceStub
-from lte.protos.policydb_pb2 import PolicyRule, FlowQos, QosArp
+from magma.common.rpc_utils import grpc_wrapper
from magma.subscriberdb.sid import SIDUtils
diff --git a/lte/gateway/python/scripts/state_cli.py b/lte/gateway/python/scripts/state_cli.py
index 1364aa0e356e..41b0515e9026 100644
--- a/lte/gateway/python/scripts/state_cli.py
+++ b/lte/gateway/python/scripts/state_cli.py
@@ -14,23 +14,22 @@
"""
import ast
import json
+import random
from json.decoder import JSONDecodeError
from typing import Union
import fire
import jsonpickle
-import random
from lte.protos.keyval_pb2 import IPDesc
from lte.protos.oai.mme_nas_state_pb2 import MmeNasState, UeContext
from lte.protos.oai.s1ap_state_pb2 import S1apState, UeDescription
from lte.protos.oai.spgw_state_pb2 import SpgwState, SpgwUeContext
from lte.protos.policydb_pb2 import InstalledPolicies, PolicyRule
-
from magma.common.redis.client import get_default_client
-from magma.common.redis.serializers import get_json_deserializer, \
- get_proto_deserializer
-from magma.mobilityd.serialize_utils import deserialize_ip_block, \
- deserialize_ip_desc
+from magma.common.redis.serializers import (get_json_deserializer,
+ get_proto_deserializer)
+from magma.mobilityd.serialize_utils import (deserialize_ip_block,
+ deserialize_ip_desc)
NO_DESERIAL_MSG = "No deserializer exists for type '{}'"
diff --git a/lte/gateway/python/scripts/subscriber_cli.py b/lte/gateway/python/scripts/subscriber_cli.py
index 5dd7a5e4e360..e92d1e1b4c42 100755
--- a/lte/gateway/python/scripts/subscriber_cli.py
+++ b/lte/gateway/python/scripts/subscriber_cli.py
@@ -15,18 +15,13 @@
import argparse
-from lte.protos.subscriberdb_pb2 import (
- GSMSubscription,
- LTESubscription,
- SubscriberData,
- SubscriberState,
- SubscriberUpdate,
-)
+from lte.protos.subscriberdb_pb2 import (GSMSubscription, LTESubscription,
+ SubscriberData, SubscriberState,
+ SubscriberUpdate)
from lte.protos.subscriberdb_pb2_grpc import SubscriberDBStub
-from orc8r.protos.common_pb2 import Void
-
from magma.common.rpc_utils import grpc_wrapper
from magma.subscriberdb.sid import SIDUtils
+from orc8r.protos.common_pb2 import Void
@grpc_wrapper
diff --git a/lte/gateway/release/Makefile b/lte/gateway/release/Makefile
index bf5e3917ba9c..06f6a6c64dfc 100644
--- a/lte/gateway/release/Makefile
+++ b/lte/gateway/release/Makefile
@@ -15,4 +15,4 @@ PY_LTE = $(MAGMA_ROOT)/lte/gateway/python
PY_ORC8R = $(MAGMA_ROOT)/orc8r/gateway/python
magma.lockfile: $(PY_LTE)/setup.py $(PY_ORC8R)/setup.py
- ./pydep finddep --install-from-official -l ./magma.lockfile $(PY_ORC8R)/setup.py $(PY_LTE)/setup.py
+ ./pydep finddep --install-from-repo -l ./magma.lockfile.$(os_release) $(PY_ORC8R)/setup.py $(PY_LTE)/setup.py
diff --git a/lte/gateway/release/build-magma.sh b/lte/gateway/release/build-magma.sh
index f0d4a09d431f..4ae5ec53834a 100755
--- a/lte/gateway/release/build-magma.sh
+++ b/lte/gateway/release/build-magma.sh
@@ -287,7 +287,7 @@ FULL_VERSION=${VERSION}-$(date +%s)-${COMMIT_HASH}
# adjust mtime of a setup.py to force update
# (e.g. `touch ${PY_LTE}/setup.py`)
pushd "${RELEASE_DIR}" || exit 1
-make -e magma.lockfile
+make os_release=$OS -e magma.lockfile
popd
cd ${PY_ORC8R}
@@ -295,15 +295,15 @@ make protos
PKG_VERSION=${FULL_VERSION} ${PY_VERSION} setup.py install --root ${PY_TMP_BUILD} --install-layout deb \
--no-compile --single-version-externally-managed
-ORC8R_PY_DEPS=`${RELEASE_DIR}/pydep lockfile ${RELEASE_DIR}/magma.lockfile`
+ORC8R_PY_DEPS=`${RELEASE_DIR}/pydep lockfile ${RELEASE_DIR}/magma.lockfile.$OS`
cd ${PY_LTE}
make protos
make swagger
PKG_VERSION=${FULL_VERSION} ${PY_VERSION} setup.py install --root ${PY_TMP_BUILD} --install-layout deb \
--no-compile --single-version-externally-managed
-${RELEASE_DIR}/pydep finddep -l ${RELEASE_DIR}/magma.lockfile setup.py
-LTE_PY_DEPS=`${RELEASE_DIR}/pydep lockfile ${RELEASE_DIR}/magma.lockfile`
+${RELEASE_DIR}/pydep finddep -l ${RELEASE_DIR}/magma.lockfile.$OS setup.py
+LTE_PY_DEPS=`${RELEASE_DIR}/pydep lockfile ${RELEASE_DIR}/magma.lockfile.$OS`
# now the binaries are built, we can package up everything else and build the
# magma package.
diff --git a/lte/gateway/release/build-ovs.sh b/lte/gateway/release/build-ovs.sh
index 07265f9d6166..74013fec0332 100755
--- a/lte/gateway/release/build-ovs.sh
+++ b/lte/gateway/release/build-ovs.sh
@@ -51,7 +51,7 @@ FLOWBASED_PATH=$(readlink -f ${MAGMA_ROOT}/third_party/gtp_ovs/kernel-4.9/gtp-v4
PATCH_ROOT=$(readlink -f "$GTP_PATCH_PATH/$OVS_VERSION_SHORT/")
VLAN_FIX="3cf2b424bb"
# be sure to increment this to enable upgrade from package repo when rebuilding identical upstream versions
-LOCAL_REV=1
+LOCAL_REV=2
# The resulting package is placed in $OUTPUT_DIR
# or in the cwd.
diff --git a/lte/gateway/release/magma-postinst b/lte/gateway/release/magma-postinst
index e5f44f2d302b..da5e9db3d8b5 100644
--- a/lte/gateway/release/magma-postinst
+++ b/lte/gateway/release/magma-postinst
@@ -16,7 +16,13 @@ sed -i "s/.*OVS_CTL_OPTS.*/OVS_CTL_OPTS='--delete-bridges'/" /etc/default/openvs
# Create /var/core directory
mkdir -p /var/core
-sudo cat /usr/local/share/magma/commit_hash > /etc/environment
+value=`cat /usr/local/share/magma/commit_hash`
+if sudo grep -q "COMMIT_HASH" /etc/environment
+then
+ sudo sed -i -e "s/^COMMIT_HASH.*/$value/" /etc/environment
+else
+ sudo cat "$value" >> /etc/environment
+fi
# Set magmad service to start on boot
systemctl enable -f magma@magmad.service
diff --git a/lte/gateway/release/magma.lockfile b/lte/gateway/release/magma.lockfile.debian
similarity index 99%
rename from lte/gateway/release/magma.lockfile
rename to lte/gateway/release/magma.lockfile.debian
index d18de275df5a..d5d2b1be6739 100644
--- a/lte/gateway/release/magma.lockfile
+++ b/lte/gateway/release/magma.lockfile.debian
@@ -438,6 +438,12 @@
"sysdep": "python3-scapy",
"version": "2.4.4"
},
+ "sentry-sdk": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-sentry-sdk",
+ "version": "1.0.0"
+ },
"simplejson": {
"root": false,
"source": "apt",
@@ -1153,6 +1159,9 @@
"scapy": {
"version": "2.4.4"
},
+ "sentry-sdk": {
+ "version": "1.0.0"
+ },
"setuptools": {
"version": "49.6.0"
},
diff --git a/lte/gateway/release/magma.lockfile.ubuntu b/lte/gateway/release/magma.lockfile.ubuntu
new file mode 100644
index 000000000000..bc4fd20de5bf
--- /dev/null
+++ b/lte/gateway/release/magma.lockfile.ubuntu
@@ -0,0 +1,1292 @@
+{
+ "dependencies": {
+ "aiodns": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-aiodns",
+ "version": "1.1.1"
+ },
+ "aioeventlet": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-aioeventlet",
+ "version": "0.5.1"
+ },
+ "aioh2": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-aioh2",
+ "version": "0.2.2"
+ },
+ "aiohttp": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-aiohttp",
+ "version": "1.2.0"
+ },
+ "argparse": {
+ "root": false,
+ "source": "pypi",
+ "sysdep": "python3-argparse",
+ "version": "1.4.0"
+ },
+ "astroid": {
+ "root": false,
+ "source": "pypi",
+ "sysdep": "python3-astroid",
+ "version": "2.4.2"
+ },
+ "attrs": {
+ "root": false,
+ "source": "pypi",
+ "sysdep": "python3-attrs",
+ "version": "20.3.0"
+ },
+ "bravado-core": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-bravado-core",
+ "version": "5.16.1"
+ },
+ "certifi": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-certifi",
+ "version": "2019.6.16"
+ },
+ "cffi": {
+ "root": false,
+ "source": "pypi",
+ "sysdep": "python3-cffi",
+ "version": "1.14.5"
+ },
+ "chardet": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-chardet",
+ "version": "3.0.4"
+ },
+ "click": {
+ "root": false,
+ "source": "pypi",
+ "sysdep": "python3-click",
+ "version": "7.1.2"
+ },
+ "cryptography": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-cryptography",
+ "version": "3.2.1"
+ },
+ "cython": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-cython",
+ "version": "0.29.1"
+ },
+ "dnspython": {
+ "root": false,
+ "source": "pypi",
+ "sysdep": "python3-dnspython",
+ "version": "1.16.0"
+ },
+ "docker": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-docker",
+ "version": "4.0.2"
+ },
+ "envoy": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-envoy",
+ "version": "0.0.3"
+ },
+ "eventlet": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-eventlet",
+ "version": "0.26.1"
+ },
+ "fire": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-fire",
+ "version": "0.2.0"
+ },
+ "flask": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-flask",
+ "version": "1.0.2"
+ },
+ "freezegun": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-freezegun",
+ "version": "0.3.15"
+ },
+ "glob2": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-glob2",
+ "version": "0.7"
+ },
+ "greenlet": {
+ "root": false,
+ "source": "pypi",
+ "sysdep": "python3-greenlet",
+ "version": "0.4.16"
+ },
+ "grpcio": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-grpcio",
+ "version": "1.36.1"
+ },
+ "h2": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-h2",
+ "version": "3.2.0"
+ },
+ "hpack": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-hpack",
+ "version": "3.0.0"
+ },
+ "hyperframe": {
+ "root": false,
+ "source": "pypi",
+ "sysdep": "python3-hyperframe",
+ "version": "5.2.0"
+ },
+ "idna": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-idna",
+ "version": "2.8"
+ },
+ "importlib-metadata": {
+ "root": false,
+ "source": "pypi",
+ "sysdep": "python3-importlib-metadata",
+ "version": "2.1.1"
+ },
+ "importlib-resources": {
+ "root": false,
+ "source": "pypi",
+ "sysdep": "python3-importlib-resources",
+ "version": "3.0.0"
+ },
+ "isort": {
+ "root": false,
+ "source": "pypi",
+ "sysdep": "python3-isort",
+ "version": "4.3.21"
+ },
+ "itsdangerous": {
+ "root": false,
+ "source": "pypi",
+ "sysdep": "python3-itsdangerous",
+ "version": "1.1.0"
+ },
+ "jinja2": {
+ "root": false,
+ "source": "pypi",
+ "sysdep": "python3-jinja2",
+ "version": "2.10"
+ },
+ "js-regex": {
+ "root": false,
+ "source": "pypi",
+ "sysdep": "python3-js-regex",
+ "version": "1.0.1"
+ },
+ "jsonpickle": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-jsonpickle",
+ "version": "0.9.3"
+ },
+ "jsonref": {
+ "root": false,
+ "source": "pypi",
+ "sysdep": "python3-jsonref",
+ "version": "0.2"
+ },
+ "jsonschema": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-jsonschema",
+ "version": "3.1.0"
+ },
+ "lazy-object-proxy": {
+ "root": false,
+ "source": "pypi",
+ "sysdep": "python3-lazy-object-proxy",
+ "version": "1.4.3"
+ },
+ "lxml": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-lxml",
+ "version": "4.6.2"
+ },
+ "markupsafe": {
+ "root": false,
+ "source": "pypi",
+ "sysdep": "python3-markupsafe",
+ "version": "1.1.1"
+ },
+ "mccabe": {
+ "root": false,
+ "source": "pypi",
+ "sysdep": "python3-mccabe",
+ "version": "0.6.1"
+ },
+ "monotonic": {
+ "root": false,
+ "source": "pypi",
+ "sysdep": "python3-monotonic",
+ "version": "1.5"
+ },
+ "msgpack": {
+ "root": false,
+ "source": "pypi",
+ "sysdep": "python3-msgpack",
+ "version": "1.0.0"
+ },
+ "netaddr": {
+ "root": false,
+ "source": "pypi",
+ "sysdep": "python3-netaddr",
+ "version": "0.8.0"
+ },
+ "netifaces": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-netifaces",
+ "version": "0.10.9"
+ },
+ "oslo.config": {
+ "root": false,
+ "source": "pypi",
+ "sysdep": "python3-oslo.config",
+ "version": "2.5.0"
+ },
+ "ovs": {
+ "root": false,
+ "source": "pypi",
+ "sysdep": "python3-ovs",
+ "version": "2.6.0"
+ },
+ "pbr": {
+ "root": false,
+ "source": "pypi",
+ "sysdep": "python3-pbr",
+ "version": "5.4.5"
+ },
+ "priority": {
+ "root": false,
+ "source": "pypi",
+ "sysdep": "python3-priority",
+ "version": "1.3.0"
+ },
+ "protobuf": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-protobuf",
+ "version": "3.14.0"
+ },
+ "psutil": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-psutil",
+ "version": "5.6.6"
+ },
+ "pycares": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-pycares",
+ "version": "3.1.1"
+ },
+ "pycparser": {
+ "root": false,
+ "source": "pypi",
+ "sysdep": "python3-pycparser",
+ "version": "2.20"
+ },
+ "pycryptodome": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-pycryptodome",
+ "version": "3.9.9"
+ },
+ "pylint": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-pylint",
+ "version": "2.6.2"
+ },
+ "pymemoize": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-pymemoize",
+ "version": "1.0.2"
+ },
+ "pyroute2": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-pyroute2",
+ "version": "0.5.14"
+ },
+ "pyrsistent": {
+ "root": false,
+ "source": "pypi",
+ "sysdep": "python3-pyrsistent",
+ "version": "0.17.3"
+ },
+ "pystemd": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-pystemd",
+ "version": "0.8.0"
+ },
+ "python-dateutil": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-python-dateutil",
+ "version": "2.8.1"
+ },
+ "python-redis-lock": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-python-redis-lock",
+ "version": "3.7.0"
+ },
+ "pytz": {
+ "root": false,
+ "source": "pypi",
+ "sysdep": "python3-pytz",
+ "version": "2020.1"
+ },
+ "pyyaml": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-yaml",
+ "version": "3.12"
+ },
+ "redis": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-redis",
+ "version": "3.5.3"
+ },
+ "redis-collections": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-redis-collections",
+ "version": "0.9.0"
+ },
+ "repoze.lru": {
+ "root": false,
+ "source": "pypi",
+ "sysdep": "python3-repoze.lru",
+ "version": "0.7"
+ },
+ "requests": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-requests",
+ "version": "2.22.0"
+ },
+ "rfc3987": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-rfc3987",
+ "version": "1.3.8"
+ },
+ "routes": {
+ "root": false,
+ "source": "pypi",
+ "sysdep": "python3-routes",
+ "version": "2.4.1"
+ },
+ "ryu": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-ryu",
+ "version": "4.30"
+ },
+ "scapy": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-scapy",
+ "version": "2.4.4"
+ },
+ "sentry-sdk": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-sentry-sdk",
+ "version": "1.0.0"
+ },
+ "simplejson": {
+ "root": false,
+ "source": "apt",
+ "sysdep": "python3-simplejson",
+ "version": "3.10.0"
+ },
+ "six": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-six",
+ "version": "1.12.0"
+ },
+ "snowflake": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-snowflake",
+ "version": "0.0.3"
+ },
+ "spyne": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-spyne",
+ "version": "2.12.16"
+ },
+ "stevedore": {
+ "root": false,
+ "source": "pypi",
+ "sysdep": "python3-stevedore",
+ "version": "1.32.0"
+ },
+ "strict-rfc3339": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-strict-rfc3339",
+ "version": "0.7"
+ },
+ "swagger-spec-validator": {
+ "root": false,
+ "source": "pypi",
+ "sysdep": "python3-swagger-spec-validator",
+ "version": "2.7.3"
+ },
+ "termcolor": {
+ "root": false,
+ "source": "apt",
+ "sysdep": "python3-termcolor",
+ "version": "1.1.0"
+ },
+ "tinyrpc": {
+ "root": false,
+ "source": "pypi",
+ "sysdep": "python3-tinyrpc",
+ "version": "1.0.4"
+ },
+ "toml": {
+ "root": false,
+ "source": "pypi",
+ "sysdep": "python3-toml",
+ "version": "0.10.2"
+ },
+ "typed-ast": {
+ "root": false,
+ "source": "pypi",
+ "sysdep": "python3-typed-ast",
+ "version": "1.4.2"
+ },
+ "urllib3": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-urllib3",
+ "version": "1.25.3"
+ },
+ "webcolors": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-webcolors",
+ "version": "1.11.1"
+ },
+ "webob": {
+ "root": false,
+ "source": "pypi",
+ "sysdep": "python3-webob",
+ "version": "1.2"
+ },
+ "websocket-client": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-websocket-client",
+ "version": "0.56.0"
+ },
+ "werkzeug": {
+ "root": false,
+ "source": "pypi",
+ "sysdep": "python3-werkzeug",
+ "version": "0.14"
+ },
+ "wrapt": {
+ "root": false,
+ "source": "pypi",
+ "sysdep": "python3-wrapt",
+ "version": "1.12.1"
+ },
+ "wsgiserver": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-wsgiserver",
+ "version": "1.3"
+ },
+ "zipp": {
+ "root": false,
+ "source": "pypi",
+ "sysdep": "python3-zipp",
+ "version": "1.2.0"
+ }
+ },
+ "override": {
+ "focal": {
+ "dependencies": {
+ "aiodns": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-aiodns",
+ "version": "2.0.0"
+ },
+ "aioh2": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-aioh2",
+ "version": "0.2.2"
+ },
+ "aiohttp": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-aiohttp",
+ "version": "3.6.2"
+ },
+ "astroid": {
+ "root": false,
+ "source": "apt",
+ "sysdep": "python3-astroid",
+ "version": "2.4.2"
+ },
+ "async-timeout": {
+ "root": false,
+ "source": "apt",
+ "sysdep": "python3-async-timeout",
+ "version": "3.0.1"
+ },
+ "attrs": {
+ "root": false,
+ "source": "pypi",
+ "sysdep": "python3-attrs",
+ "version": "19.3.0"
+ },
+ "bravado-core": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-bravado-core",
+ "version": "5.16.1"
+ },
+ "certifi": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-certifi",
+ "version": "2019.11.28"
+ },
+ "click": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-click",
+ "version": "7.1.2"
+ },
+ "cryptography": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-cryptography",
+ "version": "2.8"
+ },
+ "cython": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-cython",
+ "version": "0.29.1"
+ },
+ "docker": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-docker",
+ "version": "4.0.2"
+ },
+ "envoy": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-envoy",
+ "version": "0.0.3"
+ },
+ "eventlet": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-eventlet",
+ "version": "0.26.1"
+ },
+ "fire": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-fire",
+ "version": "0.2.1"
+ },
+ "flask": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-flask",
+ "version": "1.1.1"
+ },
+ "freezegun": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-freezegun",
+ "version": "0.3.15"
+ },
+ "glob2": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-glob2",
+ "version": "0.7"
+ },
+ "greenlet": {
+ "root": false,
+ "source": "apt",
+ "sysdep": "python3-greenlet",
+ "version": "0.4.16"
+ },
+ "grpcio": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-grpcio",
+ "version": "1.34.0"
+ },
+ "h2": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-h2",
+ "version": "3.2.0"
+ },
+ "hpack": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-hpack",
+ "version": "3.0.0"
+ },
+ "hyperframe": {
+ "root": false,
+ "source": "apt",
+ "sysdep": "python3-hyperframe",
+ "version": "5.2.0"
+ },
+ "idna": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-idna",
+ "version": "2.8"
+ },
+ "importlib-metadata": {
+ "root": false,
+ "source": "apt",
+ "sysdep": "python3-importlib-metadata",
+ "version": "1.5.0"
+ },
+ "isort": {
+ "root": false,
+ "source": "apt",
+ "sysdep": "python3-isort",
+ "version": "5.7.0"
+ },
+ "itsdangerous": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-itsdangerous",
+ "version": "1.1.0"
+ },
+ "jinja2": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-jinja2",
+ "version": "2.10.1"
+ },
+ "js-regex": {
+ "root": false,
+ "source": "apt",
+ "sysdep": "python3-js-regex",
+ "version": "1.0.1"
+ },
+ "json-pointer": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-json-pointer",
+ "version": "0.1.2"
+ },
+ "jsonpickle": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-jsonpickle",
+ "version": "1.2"
+ },
+ "jsonref": {
+ "root": false,
+ "source": "apt",
+ "sysdep": "python3-jsonref",
+ "version": "0.2"
+ },
+ "jsonschema": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-jsonschema",
+ "version": "3.1.0"
+ },
+ "lazy-object-proxy": {
+ "root": false,
+ "source": "pypi",
+ "sysdep": "python3-lazy-object-proxy",
+ "version": "1.4.3"
+ },
+ "lxml": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-lxml",
+ "version": "4.6.2"
+ },
+ "mccabe": {
+ "root": false,
+ "source": "apt",
+ "sysdep": "python3-mccabe",
+ "version": "0.6.1"
+ },
+ "msgpack": {
+ "root": false,
+ "source": "apt",
+ "sysdep": "python3-msgpack",
+ "version": "0.6.2"
+ },
+ "multidict": {
+ "root": false,
+ "source": "apt",
+ "sysdep": "python3-multidict",
+ "version": "4.7.6"
+ },
+ "netifaces": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-netifaces",
+ "version": "0.10.4"
+ },
+ "ovs": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-ovs",
+ "version": "2.13.3"
+ },
+ "priority": {
+ "root": false,
+ "source": "apt",
+ "sysdep": "python3-priority",
+ "version": "1.3.0"
+ },
+ "prometheus-client": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-prometheus-client",
+ "version": "0.3.1"
+ },
+ "protobuf": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-protobuf",
+ "version": "3.14.0"
+ },
+ "psutil": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-psutil",
+ "version": "5.6.6"
+ },
+ "pycares": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-pycares",
+ "version": "3.1.1"
+ },
+ "pycryptodome": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-pycryptodome",
+ "version": "3.9.9"
+ },
+ "pylint": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-pylint",
+ "version": "2.6.0"
+ },
+ "pymemoize": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-pymemoize",
+ "version": "1.0.2"
+ },
+ "pyrsistent": {
+ "root": false,
+ "source": "pypi",
+ "sysdep": "python3-pyrsistent",
+ "version": "0.15.5"
+ },
+ "pystemd": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-pystemd",
+ "version": "0.8.0"
+ },
+ "python-dateutil": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-python-dateutil",
+ "version": "2.8.1"
+ },
+ "python-redis-lock": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-python-redis-lock",
+ "version": "3.7.0"
+ },
+ "python3-systemd": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-systemd",
+ "version": "234"
+ },
+ "pytz": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-pytz",
+ "version": "2020.1"
+ },
+ "pyyaml": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-yaml",
+ "version": "5.3.1"
+ },
+ "redis": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-redis",
+ "version": "3.3.11"
+ },
+ "redis-collections": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-redis-collections",
+ "version": "0.8.1"
+ },
+ "rfc3987": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-rfc3987",
+ "version": "1.3.8"
+ },
+ "ryu": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-ryu",
+ "version": "4.30"
+ },
+ "scapy": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-scapy",
+ "version": "2.4.4"
+ },
+ "sentry-sdk": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-sentry-sdk",
+ "version": "1.0.0"
+ },
+ "simplejson": {
+ "root": false,
+ "source": "pypi",
+ "sysdep": "python3-simplejson",
+ "version": "3.16.0"
+ },
+ "six": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-six",
+ "version": "1.14.0"
+ },
+ "snowflake": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-snowflake",
+ "version": "0.0.3"
+ },
+ "sortedcontainers": {
+ "root": false,
+ "source": "apt",
+ "sysdep": "python3-sortedcontainers",
+ "version": "2.3.0"
+ },
+ "spyne": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-spyne",
+ "version": "2.13.16"
+ },
+ "strict-rfc3339": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-strict-rfc3339",
+ "version": "0.7"
+ },
+ "swagger-spec-validator": {
+ "root": false,
+ "source": "apt",
+ "sysdep": "python3-swagger-spec-validator",
+ "version": "2.7.3"
+ },
+ "toml": {
+ "root": false,
+ "source": "apt",
+ "sysdep": "python3-toml",
+ "version": "0.10.2"
+ },
+ "typing-extensions": {
+ "root": false,
+ "source": "apt",
+ "sysdep": "python3-typing-extensions",
+ "version": "3.7.4.3"
+ },
+ "webcolors": {
+ "root": true,
+ "source": "pypi",
+ "sysdep": "python3-webcolors",
+ "version": "1.11.1"
+ },
+ "websocket-client": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-websocket-client",
+ "version": "0.56.0"
+ },
+ "werkzeug": {
+ "root": false,
+ "source": "apt",
+ "sysdep": "python3-werkzeug",
+ "version": "0.14"
+ },
+ "wrapt": {
+ "root": false,
+ "source": "pypi",
+ "sysdep": "python3-wrapt",
+ "version": "1.11.2"
+ },
+ "wsgiserver": {
+ "root": true,
+ "source": "apt",
+ "sysdep": "python3-wsgiserver",
+ "version": "1.3"
+ },
+ "yarl": {
+ "root": false,
+ "source": "apt",
+ "sysdep": "python3-yarl",
+ "version": "1.6.3"
+ }
+ },
+ "root_packages": {
+ "aiodns": {
+ "version": "2.0.0"
+ },
+ "aioh2": {
+ "version": "0.2.2"
+ },
+ "aiohttp": {
+ "version": "3.6.2"
+ },
+ "bravado-core": {
+ "version": "5.16.1"
+ },
+ "certifi": {
+ "version": "2019.11.28"
+ },
+ "click": {
+ "version": "7.1.2"
+ },
+ "cryptography": {
+ "version": "2.8"
+ },
+ "fire": {
+ "version": "0.2.1"
+ },
+ "flask": {
+ "version": "1.1.1"
+ },
+ "grpcio": {
+ "version": "1.34.0"
+ },
+ "itsdangerous": {
+ "version": "1.1.0"
+ },
+ "jinja2": {
+ "version": "2.10.1"
+ },
+ "json-pointer": {
+ "version": "0.1.2"
+ },
+ "jsonpickle": {
+ "version": "1.2"
+ },
+ "jsonschema": {
+ "version": "3.1.0"
+ },
+ "netifaces": {
+ "version": "0.10.4"
+ },
+ "ovs": {
+ "version": "2.13.3"
+ },
+ "prometheus-client": {
+ "version": "0.3.1"
+ },
+ "protobuf": {
+ "version": "3.14.0"
+ },
+ "psutil": {
+ "version": "5.6.6"
+ },
+ "pycares": {
+ "version": "3.1.1"
+ },
+ "pylint": {
+ "version": "2.6.0"
+ },
+ "pystemd": {
+ "version": "0.8.0"
+ },
+ "pytz": {
+ "version": "2020.1"
+ },
+ "pyyaml": {
+ "version": "5.3.1"
+ },
+ "redis": {
+ "version": "3.3.11"
+ },
+ "redis-collections": {
+ "version": "0.8.1"
+ },
+ "rfc3987": {
+ "version": "1.3.8"
+ },
+ "sentry-sdk": {
+ "version": "1.0.0"
+ },
+ "setuptools": {
+ "version": "49.6.0"
+ },
+ "six": {
+ "version": "1.14.0"
+ },
+ "snowflake": {
+ "version": "0.0.3"
+ },
+ "spyne": {
+ "version": "2.13.16"
+ },
+ "strict-rfc3339": {
+ "version": "0.7"
+ },
+ "systemd": {
+ "version": "234"
+ },
+ "systemd-python": {
+ "version": "234"
+ },
+ "webcolors": {
+ "version": "1.11.1"
+ }
+ }
+ }
+ },
+ "root_packages": {
+ "aiodns": {
+ "version": "1.1.1"
+ },
+ "aioeventlet": {
+ "version": "0.5.1"
+ },
+ "aioh2": {
+ "version": "0.2.2"
+ },
+ "aiohttp": {
+ "version": "1.2.0"
+ },
+ "bravado-core": {
+ "version": "5.16.1"
+ },
+ "certifi": {
+ "version": "2019.6.16"
+ },
+ "chardet": {
+ "version": "3.0.4"
+ },
+ "click": {
+ "version": "7.1.2"
+ },
+ "cryptography": {
+ "version": "3.2.1"
+ },
+ "cython": {
+ "version": "0.29.1"
+ },
+ "docker": {
+ "version": "4.0.2"
+ },
+ "envoy": {
+ "version": "0.0.3"
+ },
+ "eventlet": {
+ "version": "0.26.1"
+ },
+ "fire": {
+ "version": "0.2.0"
+ },
+ "flask": {
+ "version": "1.0.2"
+ },
+ "freezegun": {
+ "version": "0.3.15"
+ },
+ "glob2": {
+ "version": "0.7"
+ },
+ "grpcio": {
+ "version": "1.36.1"
+ },
+ "h2": {
+ "version": "3.2.0"
+ },
+ "hpack": {
+ "version": "3.0.0"
+ },
+ "idna": {
+ "version": "2.8"
+ },
+ "itsdangerous": {
+ "version": "1.1.0"
+ },
+ "jinja2": {
+ "version": "2.10"
+ },
+ "jsonpickle": {
+ "version": "0.9.3"
+ },
+ "jsonschema": {
+ "version": "3.1.0"
+ },
+ "lxml": {
+ "version": "4.6.2"
+ },
+ "netifaces": {
+ "version": "0.10.9"
+ },
+ "protobuf": {
+ "version": "3.14.0"
+ },
+ "psutil": {
+ "version": "5.6.6"
+ },
+ "pycares": {
+ "version": "3.1.1"
+ },
+ "pycryptodome": {
+ "version": "3.9.9"
+ },
+ "pylint": {
+ "version": "2.6.2"
+ },
+ "pymemoize": {
+ "version": "1.0.2"
+ },
+ "pyroute2": {
+ "version": "0.5.14"
+ },
+ "pystemd": {
+ "version": "0.8.0"
+ },
+ "python-dateutil": {
+ "version": "2.8.1"
+ },
+ "python-redis-lock": {
+ "version": "3.7.0"
+ },
+ "pytz": {
+ "version": "2020.1"
+ },
+ "pyyaml": {
+ "version": "3.12"
+ },
+ "redis": {
+ "version": "3.5.3"
+ },
+ "redis-collections": {
+ "version": "0.9.0"
+ },
+ "requests": {
+ "version": "2.22.0"
+ },
+ "rfc3987": {
+ "version": "1.3.8"
+ },
+ "ryu": {
+ "version": "4.30"
+ },
+ "scapy": {
+ "version": "2.4.4"
+ },
+ "sentry-sdk": {
+ "version": "1.0.0"
+ },
+ "setuptools": {
+ "version": "49.6.0"
+ },
+ "six": {
+ "version": "1.12.0"
+ },
+ "snowflake": {
+ "version": "0.0.3"
+ },
+ "spyne": {
+ "version": "2.12.16"
+ },
+ "strict-rfc3339": {
+ "version": "0.7"
+ },
+ "urllib3": {
+ "version": "1.25.3"
+ },
+ "webcolors": {
+ "version": "1.11.1"
+ },
+ "websocket-client": {
+ "version": "0.56.0"
+ },
+ "wsgiserver": {
+ "version": "1.3"
+ }
+ }
+}
diff --git a/lte/gateway/release/pydep b/lte/gateway/release/pydep
index df619b8ab511..534af31d66c1 100755
--- a/lte/gateway/release/pydep
+++ b/lte/gateway/release/pydep
@@ -463,6 +463,9 @@ class Lockfile(object):
log.warning('dependencies may not be generated correctly')
self._release = release_info.get('VERSION_CODENAME', self._default_release)
+ if reference_lockfile is None:
+ reference_lockfile = "./release/magma.lockfile.{}".format(self._release)
+
def lower_keys(d: Dict[str, Any]):
return {k.lower(): v for k, v in d.items()}
@@ -1010,6 +1013,7 @@ def main(args):
with open(args.lockfile, 'r') as r:
lf = Lockfile(data=r.read())
except FileNotFoundError:
+ log.error("file not found: {}".format(args.lockfile));
pass
else:
lf = Lockfile()
diff --git a/lte/protos/pipelined.proto b/lte/protos/pipelined.proto
index c6d95e0615fe..85ce03904574 100644
--- a/lte/protos/pipelined.proto
+++ b/lte/protos/pipelined.proto
@@ -123,11 +123,11 @@ message RuleModResult {
FAILURE = 2;
}
Result result = 2;
+ uint64 version = 3;
}
message ActivateFlowsResult {
- repeated RuleModResult dynamic_rule_results = 2;
-
+ repeated RuleModResult policy_results = 2;
reserved 1;
}
diff --git a/lte/protos/subscriberdb.proto b/lte/protos/subscriberdb.proto
index da73d23bb428..6069913c4868 100644
--- a/lte/protos/subscriberdb.proto
+++ b/lte/protos/subscriberdb.proto
@@ -208,7 +208,7 @@ message SubscriberUpdate {
}
// --------------------------------------------------------------------------
-// SubscriberDB service definition.
+// SubscriberDB gateway service definition.
// --------------------------------------------------------------------------
service SubscriberDB {
@@ -236,3 +236,25 @@ service SubscriberDB {
//
rpc ListSubscribers (magma.orc8r.Void) returns (SubscriberIDSet) {}
}
+
+// --------------------------------------------------------------------------
+// SubscriberDB cloud service definition.
+// --------------------------------------------------------------------------
+service SubscriberDBCloud {
+ // ListSubscribers lists pages of subscribers stored.
+ rpc ListSubscribers (ListSubscribersRequest) returns (ListSubscribersResponse) {}
+}
+
+message ListSubscribersRequest {
+ // page_size is the maximum number of entities returned per request.
+ uint32 page_size = 1;
+ // page_token is a serialized entity page token for paginated loads.
+ string page_token = 2;
+}
+
+message ListSubscribersResponse {
+ repeated SubscriberData subscribers = 1;
+ // next_page_token is a serialized entity page token for subsequent paginated
+ // loads.
+ string next_page_token = 2;
+}
diff --git a/nms/app/package.json b/nms/app/package.json
index e94200fc22f1..afab322fb821 100644
--- a/nms/app/package.json
+++ b/nms/app/package.json
@@ -24,7 +24,7 @@
},
"devDependencies": {
"babel-eslint": "^10.1.0",
- "babel-jest": "^24.9.0",
+ "babel-jest": "^26.6.3",
"eslint": "^6.0.1",
"eslint-config-fb-strict": "^24.3.0",
"eslint-config-fbcnms": "^0.2.1",
diff --git a/nms/app/packages/magmalte/app/views/tracing/TraceStartDialog.js b/nms/app/packages/magmalte/app/views/tracing/TraceStartDialog.js
index e1d8909dd556..9b6d922a7aca 100644
--- a/nms/app/packages/magmalte/app/views/tracing/TraceStartDialog.js
+++ b/nms/app/packages/magmalte/app/views/tracing/TraceStartDialog.js
@@ -165,8 +165,9 @@ function CreateTraceDetails(props: Props) {
placeholder="Enter Trace Timeout (s)"
fullWidth={true}
value={traceCfg.timeout}
+ type="number"
onChange={({target}) => {
- setTraceCfg({...traceCfg, timeout: target.value});
+ setTraceCfg({...traceCfg, timeout: parseInt(target.value)});
}}
/>
diff --git a/nms/app/packages/magmalte/package.json b/nms/app/packages/magmalte/package.json
index 9ea7590cc4fa..f6a8fd9d9bf0 100644
--- a/nms/app/packages/magmalte/package.json
+++ b/nms/app/packages/magmalte/package.json
@@ -33,7 +33,7 @@
"@fbcnms/magma-api": "^0.1.0",
"@fbcnms/platform-server": "^0.1.23",
"@fbcnms/projects": "^0.1.0",
- "@fbcnms/sequelize-models": "^0.1.1",
+ "@fbcnms/sequelize-models": "^0.1.6",
"@fbcnms/strings": "^0.1.0",
"@fbcnms/types": "^0.1.11",
"@fbcnms/ui": "^0.1.8",
diff --git a/nms/app/packages/magmalte/scripts/fuji-upgrade/pre-upgrade-migration.sh b/nms/app/packages/magmalte/scripts/fuji-upgrade/pre-upgrade-migration.sh
index 09dcd2949a50..14392aab5208 100644
--- a/nms/app/packages/magmalte/scripts/fuji-upgrade/pre-upgrade-migration.sh
+++ b/nms/app/packages/magmalte/scripts/fuji-upgrade/pre-upgrade-migration.sh
@@ -36,19 +36,19 @@ PRE-REQUISITES
EOF
# Get the Magma k8s namespace
-read -p "Enter Kubernetes namespace [magma]: " magma_namespace
-magma_namespace=${magma_namespace:-magma}
+read -p "Enter Kubernetes namespace [orc8r]: " magma_namespace
+magma_namespace=${magma_namespace:-orc8r}
echo ""
# Find NMS pod name
-nms_pod_name=$(kubectl -n magma get pods --no-headers -o custom-columns=":metadata.name" | grep nms-magmalte)
+nms_pod_name=$(kubectl -n $magma_namespace get pods --no-headers -o custom-columns=":metadata.name" | grep nms-magmalte)
echo "Found Magma NMS pod name: $nms_pod_name"
read -p "Enter NMS pod name [$nms_pod_name]: " input
nms_pod_name=${input:-$nms_pod_name}
echo ""
# Find configurator pod name
-orc8r_pod_name=$(kubectl -n magma get pods --no-headers -o custom-columns=":metadata.name" | grep orc8r-configurator)
+orc8r_pod_name=$(kubectl -n $magma_namespace get pods --no-headers -o custom-columns=":metadata.name" | grep orc8r-configurator)
echo "Found Magma configurator pod name: $orc8r_pod_name"
read -p "Enter configurator pod name [$orc8r_pod_name]: " input
orc8r_pod_name=${input:-$orc8r_pod_name}
diff --git a/nms/app/packages/magmalte/scripts/fuji-upgrade/runs-on-nms.sh b/nms/app/packages/magmalte/scripts/fuji-upgrade/runs-on-nms.sh
index 3df4729fd622..7035b9d02a00 100644
--- a/nms/app/packages/magmalte/scripts/fuji-upgrade/runs-on-nms.sh
+++ b/nms/app/packages/magmalte/scripts/fuji-upgrade/runs-on-nms.sh
@@ -44,11 +44,11 @@ done
cat << EOF
--------------------------------------------------------------------------------
- Upgrading @fbcnms/sequelize-models to ^0.1.4
+ Upgrading @fbcnms/sequelize-models to ^0.1.6
--------------------------------------------------------------------------------
EOF
pushd /usr/src/packages/magmalte
-yarn upgrade @fbcnms/sequelize-models@^0.1.4
+yarn upgrade @fbcnms/sequelize-models@^0.1.6
yarn
popd
cat << EOF
diff --git a/nms/app/yarn.lock b/nms/app/yarn.lock
index 6d8e4dad4f08..70986d5c8adf 100644
--- a/nms/app/yarn.lock
+++ b/nms/app/yarn.lock
@@ -96,7 +96,7 @@
semver "^5.4.1"
source-map "^0.5.0"
-"@babel/generator@^7.0.0", "@babel/generator@^7.4.0":
+"@babel/generator@^7.0.0":
version "7.10.2"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.10.2.tgz#0fa5b5b2389db8bfdfcc3492b551ee20f5dd69a9"
integrity sha512-AxfBNHNu99DTMvlUPlt1h2+Hn7knPpH5ayJ8OqDWSeLld+Fi2AYBTC/IejWDM9Edcii4UzZRCsbUt0WlSDsDsA==
@@ -359,7 +359,7 @@
regenerator-runtime "^0.13.4"
v8flags "^3.1.1"
-"@babel/parser@^7.0.0", "@babel/parser@^7.4.3", "@babel/parser@^7.7.0":
+"@babel/parser@^7.0.0", "@babel/parser@^7.7.0":
version "7.10.2"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.10.2.tgz#871807f10442b92ff97e4783b9b54f6a0ca812d0"
integrity sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==
@@ -1216,15 +1216,6 @@
"@babel/parser" "^7.12.7"
"@babel/types" "^7.12.7"
-"@babel/template@^7.4.0":
- version "7.10.1"
- resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.1.tgz#e167154a94cb5f14b28dc58f5356d2162f539811"
- integrity sha512-OQDg6SqvFSsc9A0ej6SKINWrpJiNonRIniYondK2ViKhB06i3c0s+76XUft71iqBEe9S1OKsHwPAjfHnuvnCig==
- dependencies:
- "@babel/code-frame" "^7.10.1"
- "@babel/parser" "^7.10.1"
- "@babel/types" "^7.10.1"
-
"@babel/traverse@^7.1.0", "@babel/traverse@^7.10.4", "@babel/traverse@^7.12.1", "@babel/traverse@^7.12.10", "@babel/traverse@^7.12.5", "@babel/traverse@^7.12.9":
version "7.12.10"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.10.tgz#2d1f4041e8bf42ea099e5b2dc48d6a594c00017a"
@@ -1240,7 +1231,7 @@
globals "^11.1.0"
lodash "^4.17.19"
-"@babel/traverse@^7.4.3", "@babel/traverse@^7.7.0":
+"@babel/traverse@^7.7.0":
version "7.10.1"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.10.1.tgz#bbcef3031e4152a6c0b50147f4958df54ca0dd27"
integrity sha512-C/cTuXeKt85K+p08jN6vMDz8vSV0vZcI0wmQ36o6mjbuo++kPMdpOYw23W2XH04dbRt9/nMEfA4W3eR21CD+TQ==
@@ -1264,7 +1255,7 @@
lodash "^4.17.19"
to-fast-properties "^2.0.0"
-"@babel/types@^7.0.0-beta.49", "@babel/types@^7.10.2", "@babel/types@^7.4.0", "@babel/types@^7.6.1", "@babel/types@^7.7.0", "@babel/types@^7.9.6":
+"@babel/types@^7.0.0-beta.49", "@babel/types@^7.10.2", "@babel/types@^7.6.1", "@babel/types@^7.7.0", "@babel/types@^7.9.6":
version "7.11.5"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.11.5.tgz#d9de577d01252d77c6800cee039ee64faf75662d"
integrity sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==
@@ -1562,6 +1553,17 @@
dependencies:
sequelize "^5.8.5"
+"@fbcnms/sequelize-models@^0.1.6":
+ version "0.1.6"
+ resolved "https://registry.yarnpkg.com/@fbcnms/sequelize-models/-/sequelize-models-0.1.6.tgz#4d4278b9c59469f17e7851f514189cff703173ea"
+ integrity sha512-xQoF4w+6qo18gwS+kQYo5aCPpSvX9ZYIrAEp4EalQs+X5QkeKeHJs3a5c6SO8/wnMKsOX7Tdo0bg2Oa9Fgdc/w==
+ dependencies:
+ "@fbcnms/babel-register" "^0.1.0"
+ inquirer "^8.0.0"
+ mariadb "^2.4.2"
+ minimist "^1.2.5"
+ sequelize "^5.8.5"
+
"@fbcnms/strings@^0.1.0":
version "0.1.0"
resolved "https://registry.yarnpkg.com/@fbcnms/strings/-/strings-0.1.0.tgz#50dae22b4cb7cb7d1a30c013d0b40c96b741a1f1"
@@ -1626,15 +1628,6 @@
resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.2.tgz#26520bf09abe4a5644cd5414e37125a8954241dd"
integrity sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==
-"@jest/console@^24.9.0":
- version "24.9.0"
- resolved "https://registry.yarnpkg.com/@jest/console/-/console-24.9.0.tgz#79b1bc06fb74a8cfb01cbdedf945584b1b9707f0"
- integrity sha512-Zuj6b8TnKXi3q4ymac8EQfc3ea/uhLeCGThFqXeC8H9/raaH8ARPUTdId+XyGd03Z4In0/VjD2OYFcBF09fNLQ==
- dependencies:
- "@jest/source-map" "^24.9.0"
- chalk "^2.0.1"
- slash "^2.0.0"
-
"@jest/console@^26.6.2":
version "26.6.2"
resolved "https://registry.yarnpkg.com/@jest/console/-/console-26.6.2.tgz#4e04bc464014358b03ab4937805ee36a0aeb98f2"
@@ -1691,15 +1684,6 @@
"@types/node" "*"
jest-mock "^26.6.2"
-"@jest/fake-timers@^24.9.0":
- version "24.9.0"
- resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-24.9.0.tgz#ba3e6bf0eecd09a636049896434d306636540c93"
- integrity sha512-eWQcNa2YSwzXWIMC5KufBh3oWRIijrQFROsIqt6v/NS9Io/gknw1jsAC9c+ih/RQX4A3O7SeWAhQeN0goKhT9A==
- dependencies:
- "@jest/types" "^24.9.0"
- jest-message-util "^24.9.0"
- jest-mock "^24.9.0"
-
"@jest/fake-timers@^26.6.2":
version "26.6.2"
resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-26.6.2.tgz#459c329bcf70cee4af4d7e3f3e67848123535aad"
@@ -1753,15 +1737,6 @@
optionalDependencies:
node-notifier "^8.0.0"
-"@jest/source-map@^24.9.0":
- version "24.9.0"
- resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-24.9.0.tgz#0e263a94430be4b41da683ccc1e6bffe2a191714"
- integrity sha512-/Xw7xGlsZb4MJzNDgB7PW5crou5JqWiBQaz6xyPd3ArOg2nfn/PunV8+olXbbEZzNl591o5rWKE9BRDaFAuIBg==
- dependencies:
- callsites "^3.0.0"
- graceful-fs "^4.1.15"
- source-map "^0.6.0"
-
"@jest/source-map@^26.6.2":
version "26.6.2"
resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-26.6.2.tgz#29af5e1e2e324cafccc936f218309f54ab69d535"
@@ -1771,15 +1746,6 @@
graceful-fs "^4.2.4"
source-map "^0.6.0"
-"@jest/test-result@^24.9.0":
- version "24.9.0"
- resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-24.9.0.tgz#11796e8aa9dbf88ea025757b3152595ad06ba0ca"
- integrity sha512-XEFrHbBonBJ8dGp2JmF8kP/nQI/ImPpygKHwQ/SY+es59Z3L5PI4Qb9TQQMAEeYsThG1xF0k6tmG0tIKATNiiA==
- dependencies:
- "@jest/console" "^24.9.0"
- "@jest/types" "^24.9.0"
- "@types/istanbul-lib-coverage" "^2.0.0"
-
"@jest/test-result@^26.6.2":
version "26.6.2"
resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-26.6.2.tgz#55da58b62df134576cc95476efa5f7949e3f5f18"
@@ -1801,28 +1767,6 @@
jest-runner "^26.6.3"
jest-runtime "^26.6.3"
-"@jest/transform@^24.9.0":
- version "24.9.0"
- resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-24.9.0.tgz#4ae2768b296553fadab09e9ec119543c90b16c56"
- integrity sha512-TcQUmyNRxV94S0QpMOnZl0++6RMiqpbH/ZMccFB/amku6Uwvyb1cjYX7xkp5nGNkbX4QPH/FcB6q1HBTHynLmQ==
- dependencies:
- "@babel/core" "^7.1.0"
- "@jest/types" "^24.9.0"
- babel-plugin-istanbul "^5.1.0"
- chalk "^2.0.1"
- convert-source-map "^1.4.0"
- fast-json-stable-stringify "^2.0.0"
- graceful-fs "^4.1.15"
- jest-haste-map "^24.9.0"
- jest-regex-util "^24.9.0"
- jest-util "^24.9.0"
- micromatch "^3.1.10"
- pirates "^4.0.1"
- realpath-native "^1.1.0"
- slash "^2.0.0"
- source-map "^0.6.1"
- write-file-atomic "2.4.1"
-
"@jest/transform@^26.6.2":
version "26.6.2"
resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-26.6.2.tgz#5ac57c5fa1ad17b2aae83e73e45813894dcf2e4b"
@@ -2411,17 +2355,6 @@
"@types/babel__template" "*"
"@types/babel__traverse" "*"
-"@types/babel__core@^7.1.0":
- version "7.1.9"
- resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.9.tgz#77e59d438522a6fb898fa43dc3455c6e72f3963d"
- integrity sha512-sY2RsIJ5rpER1u3/aQ8OFSI7qGIy8o1NEEbgb2UaJcvOtXOMpd39ko723NBpjQFg9SIX7TXtjejZVGeIMLhoOw==
- dependencies:
- "@babel/parser" "^7.1.0"
- "@babel/types" "^7.0.0"
- "@types/babel__generator" "*"
- "@types/babel__template" "*"
- "@types/babel__traverse" "*"
-
"@types/babel__generator@*":
version "7.6.2"
resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.2.tgz#f3d71178e187858f7c45e30380f8f1b7415a12d8"
@@ -2601,11 +2534,6 @@
"@types/prop-types" "*"
csstype "^3.0.2"
-"@types/stack-utils@^1.0.1":
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e"
- integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==
-
"@types/stack-utils@^2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.0.tgz#7036640b4e21cc2f259ae826ce843d277dad8cff"
@@ -3337,19 +3265,6 @@ babel-eslint@^10.1.0:
eslint-visitor-keys "^1.0.0"
resolve "^1.12.0"
-babel-jest@^24.9.0:
- version "24.9.0"
- resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-24.9.0.tgz#3fc327cb8467b89d14d7bc70e315104a783ccd54"
- integrity sha512-ntuddfyiN+EhMw58PTNL1ph4C9rECiQXjI4nMMBKBaNjXvqLdkXpPRcMSr4iyBrJg/+wz9brFUD6RhOAT6r4Iw==
- dependencies:
- "@jest/transform" "^24.9.0"
- "@jest/types" "^24.9.0"
- "@types/babel__core" "^7.1.0"
- babel-plugin-istanbul "^5.1.0"
- babel-preset-jest "^24.9.0"
- chalk "^2.4.2"
- slash "^2.0.0"
-
babel-jest@^26.6.3:
version "26.6.3"
resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-26.6.3.tgz#d87d25cb0037577a0c89f82e5755c5d293c01056"
@@ -3420,16 +3335,6 @@ babel-plugin-fbt@^0.10.4:
shelljs "^0.7.8"
yargs "^9.0.0"
-babel-plugin-istanbul@^5.1.0:
- version "5.2.0"
- resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz#df4ade83d897a92df069c4d9a25cf2671293c854"
- integrity sha512-5LphC0USA8t4i1zCtjbbNb6jJj/9+X6P37Qfirc/70EQ34xKlMW+a1RHGwxGI+SwWpNwZ27HqvzAobeqaXwiZw==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
- find-up "^3.0.0"
- istanbul-lib-instrument "^3.3.0"
- test-exclude "^5.2.3"
-
babel-plugin-istanbul@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz#e159ccdc9af95e0b570c75b4573b7c34d671d765"
@@ -3441,13 +3346,6 @@ babel-plugin-istanbul@^6.0.0:
istanbul-lib-instrument "^4.0.0"
test-exclude "^6.0.0"
-babel-plugin-jest-hoist@^24.9.0:
- version "24.9.0"
- resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.9.0.tgz#4f837091eb407e01447c8843cbec546d0002d756"
- integrity sha512-2EMA2P8Vp7lG0RAzr4HXqtYwacfMErOuv1U3wrvxHX6rD1sV6xS3WXG3r8TRQ2r6w8OhvSdWt+z41hQNwNm3Xw==
- dependencies:
- "@types/babel__traverse" "^7.0.6"
-
babel-plugin-jest-hoist@^26.6.2:
version "26.6.2"
resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz#8185bd030348d254c6d7dd974355e6a28b21e62d"
@@ -3539,14 +3437,6 @@ babel-preset-fbjs@^3.2.0:
"@babel/plugin-transform-template-literals" "^7.0.0"
babel-plugin-syntax-trailing-function-commas "^7.0.0-beta.0"
-babel-preset-jest@^24.9.0:
- version "24.9.0"
- resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-24.9.0.tgz#192b521e2217fb1d1f67cf73f70c336650ad3cdc"
- integrity sha512-izTUuhE4TMfTRPF92fFwD2QfdXaZW08qvWTFCI51V8rW5x00UuPgc3ajRoWofXOuxjfcOM5zzSYsQS3H8KGCAg==
- dependencies:
- "@babel/plugin-syntax-object-rest-spread" "^7.0.0"
- babel-plugin-jest-hoist "^24.9.0"
-
babel-preset-jest@^26.6.2:
version "26.6.2"
resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz#747872b1171df032252426586881d62d31798fee"
@@ -4378,6 +4268,11 @@ cli-width@^2.0.0:
resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.1.tgz#b0433d0b4e9c847ef18868a4ef16fd5fc8271c48"
integrity sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==
+cli-width@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6"
+ integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==
+
cli@~1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/cli/-/cli-1.0.1.tgz#22817534f24bfa4950c34d532d48ecbc621b8c14"
@@ -5696,23 +5591,6 @@ es-abstract@^1.17.0-next.1, es-abstract@^1.17.5:
string.prototype.trimend "^1.0.1"
string.prototype.trimstart "^1.0.1"
-es-abstract@^1.17.2:
- version "1.17.6"
- resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.6.tgz#9142071707857b2cacc7b89ecb670316c3e2d52a"
- integrity sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==
- dependencies:
- es-to-primitive "^1.2.1"
- function-bind "^1.1.1"
- has "^1.0.3"
- has-symbols "^1.0.1"
- is-callable "^1.2.0"
- is-regex "^1.1.0"
- object-inspect "^1.7.0"
- object-keys "^1.1.1"
- object.assign "^4.1.0"
- string.prototype.trimend "^1.0.1"
- string.prototype.trimstart "^1.0.1"
-
es-abstract@^1.18.0-next.0, es-abstract@^1.18.0-next.1:
version "1.18.0-next.1"
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0-next.1.tgz#6e3a0a4bda717e5023ab3b8e90bec36108d22c68"
@@ -7738,6 +7616,25 @@ inquirer@^7.0.0:
strip-ansi "^6.0.0"
through "^2.3.6"
+inquirer@^8.0.0:
+ version "8.0.0"
+ resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.0.0.tgz#957a46db1abcf0fdd2ab82deb7470e90afc7d0ac"
+ integrity sha512-ON8pEJPPCdyjxj+cxsYRe6XfCJepTxANdNnTebsTuQgXpRyZRRT9t4dJwjRubgmvn20CLSEnozRUayXyM9VTXA==
+ dependencies:
+ ansi-escapes "^4.2.1"
+ chalk "^4.1.0"
+ cli-cursor "^3.1.0"
+ cli-width "^3.0.0"
+ external-editor "^3.0.3"
+ figures "^3.0.0"
+ lodash "^4.17.21"
+ mute-stream "0.0.8"
+ run-async "^2.4.0"
+ rxjs "^6.6.6"
+ string-width "^4.1.0"
+ strip-ansi "^6.0.0"
+ through "^2.3.6"
+
internal-slot@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.2.tgz#9c2e9fb3cd8e5e4256c6f45fe310067fcfa378a3"
@@ -7863,7 +7760,7 @@ is-buffer@^2.0.2:
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623"
integrity sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==
-is-callable@^1.1.4, is-callable@^1.2.0, is-callable@^1.2.2:
+is-callable@^1.1.4, is-callable@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.2.tgz#c7c6715cd22d4ddb48d3e19970223aceabb080d9"
integrity sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==
@@ -8157,7 +8054,7 @@ is-regex@^1.0.3, is-regex@^1.0.4:
dependencies:
has-symbols "^1.0.1"
-is-regex@^1.1.0, is-regex@^1.1.1:
+is-regex@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.1.tgz#c6f98aacc546f6cec5468a07b7b153ab564a57b9"
integrity sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==
@@ -8278,29 +8175,11 @@ isstream@~0.1.2:
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
-istanbul-lib-coverage@^2.0.5:
- version "2.0.5"
- resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz#675f0ab69503fad4b1d849f736baaca803344f49"
- integrity sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==
-
istanbul-lib-coverage@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz#f5944a37c70b550b02a78a5c3b2055b280cec8ec"
integrity sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==
-istanbul-lib-instrument@^3.3.0:
- version "3.3.0"
- resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz#a5f63d91f0bbc0c3e479ef4c5de027335ec6d630"
- integrity sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==
- dependencies:
- "@babel/generator" "^7.4.0"
- "@babel/parser" "^7.4.3"
- "@babel/template" "^7.4.0"
- "@babel/traverse" "^7.4.3"
- "@babel/types" "^7.4.0"
- istanbul-lib-coverage "^2.0.5"
- semver "^6.0.0"
-
istanbul-lib-instrument@^4.0.0, istanbul-lib-instrument@^4.0.3:
version "4.0.3"
resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz#873c6fff897450118222774696a3f28902d77c1d"
@@ -8491,25 +8370,6 @@ jest-get-type@^26.3.0:
resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-26.3.0.tgz#e97dc3c3f53c2b406ca7afaed4493b1d099199e0"
integrity sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==
-jest-haste-map@^24.9.0:
- version "24.9.0"
- resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.9.0.tgz#b38a5d64274934e21fa417ae9a9fbeb77ceaac7d"
- integrity sha512-kfVFmsuWui2Sj1Rp1AJ4D9HqJwE4uwTlS/vO+eRUaMmd54BFpli2XhMQnPC2k4cHFVbB2Q2C+jtI1AGLgEnCjQ==
- dependencies:
- "@jest/types" "^24.9.0"
- anymatch "^2.0.0"
- fb-watchman "^2.0.0"
- graceful-fs "^4.1.15"
- invariant "^2.2.4"
- jest-serializer "^24.9.0"
- jest-util "^24.9.0"
- jest-worker "^24.9.0"
- micromatch "^3.1.10"
- sane "^4.0.3"
- walker "^1.0.7"
- optionalDependencies:
- fsevents "^1.2.7"
-
jest-haste-map@^26.6.2:
version "26.6.2"
resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-26.6.2.tgz#dd7e60fe7dc0e9f911a23d79c5ff7fb5c2cafeaa"
@@ -8583,20 +8443,6 @@ jest-matcher-utils@^26.6.2:
jest-get-type "^26.3.0"
pretty-format "^26.6.2"
-jest-message-util@^24.9.0:
- version "24.9.0"
- resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-24.9.0.tgz#527f54a1e380f5e202a8d1149b0ec872f43119e3"
- integrity sha512-oCj8FiZ3U0hTP4aSui87P4L4jC37BtQwUMqk+zk/b11FR19BJDeZsZAvIHutWnmtw7r85UmR3CEWZ0HWU2mAlw==
- dependencies:
- "@babel/code-frame" "^7.0.0"
- "@jest/test-result" "^24.9.0"
- "@jest/types" "^24.9.0"
- "@types/stack-utils" "^1.0.1"
- chalk "^2.0.1"
- micromatch "^3.1.10"
- slash "^2.0.0"
- stack-utils "^1.0.1"
-
jest-message-util@^26.6.2:
version "26.6.2"
resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-26.6.2.tgz#58173744ad6fc0506b5d21150b9be56ef001ca07"
@@ -8612,13 +8458,6 @@ jest-message-util@^26.6.2:
slash "^3.0.0"
stack-utils "^2.0.2"
-jest-mock@^24.9.0:
- version "24.9.0"
- resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.9.0.tgz#c22835541ee379b908673ad51087a2185c13f1c6"
- integrity sha512-3BEYN5WbSq9wd+SyLDES7AHnjH9A/ROBwmz7l2y+ol+NtSFO8DYiEBzoO1CeFc9a8DYy10EO4dDFVv/wN3zl1w==
- dependencies:
- "@jest/types" "^24.9.0"
-
jest-mock@^26.6.2:
version "26.6.2"
resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-26.6.2.tgz#d6cb712b041ed47fe0d9b6fc3474bc6543feb302"
@@ -8632,11 +8471,6 @@ jest-pnp-resolver@^1.2.2:
resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c"
integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==
-jest-regex-util@^24.9.0:
- version "24.9.0"
- resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-24.9.0.tgz#c13fb3380bde22bf6575432c493ea8fe37965636"
- integrity sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA==
-
jest-regex-util@^26.0.0:
version "26.0.0"
resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-26.0.0.tgz#d25e7184b36e39fd466c3bc41be0971e821fee28"
@@ -8724,11 +8558,6 @@ jest-runtime@^26.6.3:
strip-bom "^4.0.0"
yargs "^15.4.1"
-jest-serializer@^24.9.0:
- version "24.9.0"
- resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.9.0.tgz#e6d7d7ef96d31e8b9079a714754c5d5c58288e73"
- integrity sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ==
-
jest-serializer@^26.6.2:
version "26.6.2"
resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-26.6.2.tgz#d139aafd46957d3a448f3a6cdabe2919ba0742d1"
@@ -8759,24 +8588,6 @@ jest-snapshot@^26.6.2:
pretty-format "^26.6.2"
semver "^7.3.2"
-jest-util@^24.9.0:
- version "24.9.0"
- resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-24.9.0.tgz#7396814e48536d2e85a37de3e4c431d7cb140162"
- integrity sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg==
- dependencies:
- "@jest/console" "^24.9.0"
- "@jest/fake-timers" "^24.9.0"
- "@jest/source-map" "^24.9.0"
- "@jest/test-result" "^24.9.0"
- "@jest/types" "^24.9.0"
- callsites "^3.0.0"
- chalk "^2.0.1"
- graceful-fs "^4.1.15"
- is-ci "^2.0.0"
- mkdirp "^0.5.1"
- slash "^2.0.0"
- source-map "^0.6.0"
-
jest-util@^26.6.2:
version "26.6.2"
resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-26.6.2.tgz#907535dbe4d5a6cb4c47ac9b926f6af29576cbc1"
@@ -8814,14 +8625,6 @@ jest-watcher@^26.6.2:
jest-util "^26.6.2"
string-length "^4.0.1"
-jest-worker@^24.9.0:
- version "24.9.0"
- resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.9.0.tgz#5dbfdb5b2d322e98567898238a9697bcce67b3e5"
- integrity sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==
- dependencies:
- merge-stream "^2.0.0"
- supports-color "^6.1.0"
-
jest-worker@^26.6.2:
version "26.6.2"
resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed"
@@ -9276,16 +9079,6 @@ load-json-file@^2.0.0:
pify "^2.0.0"
strip-bom "^3.0.0"
-load-json-file@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b"
- integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs=
- dependencies:
- graceful-fs "^4.1.2"
- parse-json "^4.0.0"
- pify "^3.0.0"
- strip-bom "^3.0.0"
-
loader-runner@^2.4.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357"
@@ -9382,6 +9175,11 @@ lodash@^4.17.10, lodash@^4.17.14, lodash@~4.17.11:
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b"
integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==
+lodash@^4.17.21:
+ version "4.17.21"
+ resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
+ integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
+
logform@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/logform/-/logform-2.2.0.tgz#40f036d19161fc76b68ab50fdc7fe495544492f2"
@@ -10360,7 +10158,7 @@ object-copy@^0.1.0:
define-property "^0.2.5"
kind-of "^3.0.3"
-object-inspect@^1.7.0, object-inspect@^1.8.0:
+object-inspect@^1.8.0:
version "1.9.0"
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.9.0.tgz#c90521d74e1127b67266ded3394ad6116986533a"
integrity sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==
@@ -10424,14 +10222,6 @@ object.getownpropertydescriptors@^2.0.3:
define-properties "^1.1.3"
es-abstract "^1.18.0-next.1"
-object.getownpropertydescriptors@^2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz#369bf1f9592d8ab89d712dced5cb81c7c5352649"
- integrity sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==
- dependencies:
- define-properties "^1.1.3"
- es-abstract "^1.17.0-next.1"
-
object.pick@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747"
@@ -10888,13 +10678,6 @@ path-type@^2.0.0:
dependencies:
pify "^2.0.0"
-path-type@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f"
- integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==
- dependencies:
- pify "^3.0.0"
-
path-type@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
@@ -12083,14 +11866,6 @@ read-pkg-up@^2.0.0:
find-up "^2.0.0"
read-pkg "^2.0.0"
-read-pkg-up@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-4.0.0.tgz#1b221c6088ba7799601c808f91161c66e58f8978"
- integrity sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==
- dependencies:
- find-up "^3.0.0"
- read-pkg "^3.0.0"
-
read-pkg-up@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz#f3a6135758459733ae2b95638056e1854e7ef507"
@@ -12109,15 +11884,6 @@ read-pkg@^2.0.0:
normalize-package-data "^2.3.2"
path-type "^2.0.0"
-read-pkg@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389"
- integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=
- dependencies:
- load-json-file "^4.0.0"
- normalize-package-data "^2.3.2"
- path-type "^3.0.0"
-
read-pkg@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc"
@@ -12183,13 +11949,6 @@ readdirp@~3.5.0:
dependencies:
picomatch "^2.2.1"
-realpath-native@^1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.1.0.tgz#2003294fea23fb0672f2476ebe22fcf498a2d65c"
- integrity sha512-wlgPA6cCIIg9gKz0fgAPjnzh4yR/LnXovwuo9hvyGvx3h8nX4+/iLZplfUWasXpqD8BdnGnP5njOFjkUwPzvjA==
- dependencies:
- util.promisify "^1.0.0"
-
rebass@^4.0.7:
version "4.0.7"
resolved "https://registry.yarnpkg.com/rebass/-/rebass-4.0.7.tgz#0a84e5558750c1f416c3baf41ec4c7fc8d64a98a"
@@ -12689,6 +12448,13 @@ rxjs@^6.5.3:
dependencies:
tslib "^1.9.0"
+rxjs@^6.6.6:
+ version "6.6.7"
+ resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9"
+ integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==
+ dependencies:
+ tslib "^1.9.0"
+
safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
version "5.1.2"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
@@ -13279,11 +13045,6 @@ stack-trace@0.0.x:
resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0"
integrity sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=
-stack-utils@^1.0.1:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.2.tgz#33eba3897788558bebfc2db059dc158ec36cebb8"
- integrity sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==
-
stack-utils@^2.0.2:
version "2.0.3"
resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.3.tgz#cd5f030126ff116b78ccb3c027fe302713b61277"
@@ -13763,16 +13524,6 @@ terser@^4.1.2:
source-map "~0.6.1"
source-map-support "~0.5.12"
-test-exclude@^5.2.3:
- version "5.2.3"
- resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-5.2.3.tgz#c3d3e1e311eb7ee405e092dac10aefd09091eac0"
- integrity sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==
- dependencies:
- glob "^7.1.3"
- minimatch "^3.0.4"
- read-pkg-up "^4.0.0"
- require-main-filename "^2.0.0"
-
test-exclude@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e"
@@ -14431,16 +14182,6 @@ util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1:
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
-util.promisify@^1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.1.tgz#6baf7774b80eeb0f7520d8b81d07982a59abbaee"
- integrity sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==
- dependencies:
- define-properties "^1.1.3"
- es-abstract "^1.17.2"
- has-symbols "^1.0.1"
- object.getownpropertydescriptors "^2.1.0"
-
util@0.10.3:
version "0.10.3"
resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9"
@@ -14924,15 +14665,6 @@ wrappy@1:
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
-write-file-atomic@2.4.1:
- version "2.4.1"
- resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.1.tgz#d0b05463c188ae804396fd5ab2a370062af87529"
- integrity sha512-TGHFeZEZMnv+gBFRfjAcxL5bPHrsGKtnb4qsFAws7/vlh+QfwAaySIw4AXP9ZskTTh5GWu3FLuJhsWVdiJPGvg==
- dependencies:
- graceful-fs "^4.1.11"
- imurmurhash "^0.1.4"
- signal-exit "^3.0.2"
-
write-file-atomic@^2.0.0:
version "2.4.3"
resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.3.tgz#1fd2e9ae1df3e75b8d8c367443c692d4ca81f481"
diff --git a/orc8r/cloud/deploy/bare-metal-ansible/README.md b/orc8r/cloud/deploy/bare-metal-ansible/README.md
index 4dcfe2a9648d..e39b41cde794 100644
--- a/orc8r/cloud/deploy/bare-metal-ansible/README.md
+++ b/orc8r/cloud/deploy/bare-metal-ansible/README.md
@@ -9,12 +9,12 @@ hide_title: true
This page walks through a full, vanilla Orchestrator install using Ansible on bare metal or a virtual machine.
If you want to install a specific release version, see the notes in the
-[deployment intro](./deploy_intro.md).
+[deployment intro](https://docs.magmacore.org/docs/orc8r/deploy_intro).
## Prerequisites
We assume `MAGMA_ROOT` is set as described in the
-[deployment intro](./deploy_intro.md).
+[deployment intro](https://docs.magmacore.org/docs/orc8r/deploy_intro).
This walkthrough assumes you already have the following
@@ -128,25 +128,18 @@ upstream_dns_servers:
# orc8r_nms_db_pass:
# orc8r_nms_admin_pass:
```
-Once you've configured Ansible it's time to run the deployment.
+
+Once you've configured the Ansible vars file, it's time to run the deployment.
+
## Deploy the Orchestrator
-We're almost ready to deploy the orchestrator. First edit the deployment script:
-```bash
-vi $MAGMA_ROOT/orc8r/cloud/deploy/bare-metal-ansible/deploy.sh
-```
-Search for a line that reads:
+We're almost ready to deploy the orchestrator. The last step is to set the IP for the target host(s), as in:
```bash
-# Copy ``inventory/sample`` as ``inventory/$CLUSTER_NAME``
-```
-and edit the script to read:
-```bash
-mkdir -p ../inventory/$CLUSTER_NAME
-# Copy ``inventory/sample`` as ``inventory/$CLUSTER_NAME``
+export IPS=192.168.1.180
```
-The last step is to set the IP for the target host, as in:
+or if you have multiple hosts:
```bash
-export IPS=192.168.1.180
+export IPS=192.168.1.180 192.168.181 192.168.1.182
```
Now you're ready to run the deployment. From the `$MAGMA_ROOT/orc8r/cloud/deploy/bare-metal-ansible' directory, execute:
@@ -158,6 +151,6 @@ Now you're ready to run the deployment. From the `$MAGMA_ROOT/orc8r/cloud/deplo
Once you've begun a deployment, if you find that you need to go back and start again, it's best to completely reset the environment with:
```bash
-cd $MAGMA_ROOT
+cd $MAGMA_ROOT/orc8r/cloud/deploy/bare-metal-ansible/
ansible-playbook -i inventory/cluster.local/hosts.yaml -b kubespray/reset.yml
```
diff --git a/orc8r/cloud/deploy/orc8r_deployer/docker/Dockerfile b/orc8r/cloud/deploy/orc8r_deployer/docker/Dockerfile
new file mode 100644
index 000000000000..ccc2d91e3b05
--- /dev/null
+++ b/orc8r/cloud/deploy/orc8r_deployer/docker/Dockerfile
@@ -0,0 +1,71 @@
+FROM python:3.9-slim-buster
+
+ARG HELM_VERSION="3.5.1"
+ARG TERRAFORM_VERSION="0.14.7"
+ARG KUBECTL_VERSION="1.20.2"
+ARG ANSIBLE_VERSION="3.0.0"
+
+RUN apt-get update && \
+ apt-get upgrade -y && \
+ apt-get install -y \
+ git \
+ wget \
+ unzip \
+ curl \
+ vim \
+ jq \
+ procps && \
+ apt-get clean -y && \
+ apt-get autoclean -y && \
+ apt-get autoremove -y && \
+ rm -rf /var/lib/apt/lists/* && \
+ rm -rf /var/cache/apt/archives/*
+
+RUN pip3 install --no-cache-dir \
+ boto \
+ boto3 \
+ ansible==${ANSIBLE_VERSION} \
+ prettytable \
+ requests \
+ docker \
+ pyOpenSSL \
+ unittest2 \
+ colorama
+WORKDIR /root/download
+
+# Install aws cli
+RUN wget "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -O "/root/download/awscli2.zip" && \
+ unzip awscli2.zip && \
+ ./aws/install
+
+# Install aws iam authenticator
+RUN wget https://amazon-eks.s3.us-west-2.amazonaws.com/1.18.9/2020-11-02/bin/linux/amd64/aws-iam-authenticator -O /usr/local/bin/aws-iam-authenticator && \
+ chmod +x /usr/local/bin/aws-iam-authenticator
+
+# Install helm
+RUN mkdir helm3 && \
+ curl -SsL --retry 5 "https://get.helm.sh/helm-v$HELM_VERSION-linux-amd64.tar.gz" | tar xz -C ./helm3 && \
+ cp /root/download/helm3/linux-amd64/helm /usr/local/bin/helm
+
+# Install terraform
+RUN wget https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform\_${TERRAFORM_VERSION}\_linux_amd64.zip && \
+ unzip ./terraform\_${TERRAFORM_VERSION}\_linux_amd64.zip -d terraform14_cli && \
+ cp /root/download/terraform14_cli/terraform /usr/local/bin/terraform && \
+ wget https://storage.googleapis.com/kubernetes-release/release/v$KUBECTL_VERSION/bin/linux/amd64/kubectl -O /usr/local/bin/kubectl && \
+ chmod +x /usr/local/bin/kubectl && \
+ rm -rf /root/download/*
+
+COPY root/ /root/
+
+# Install the orc8r cli (orcl)
+WORKDIR /root/scripts
+RUN pip3 install .
+
+# Set these environment variables to ensure aws configuration remains
+# in the deployment directory even when container is removed
+ENV AWS_CONFIG_FILE=/root/project/.aws/config
+ENV AWS_SHARED_CREDENTIALS_FILE=/root/project/.aws/credentials
+ENV AWS_DEFAULT_OUTPUT=json
+
+WORKDIR /root/project
+CMD ["/bin/bash"]
diff --git a/orc8r/cloud/deploy/orc8r_deployer/docker/README.md b/orc8r/cloud/deploy/orc8r_deployer/docker/README.md
new file mode 100644
index 000000000000..8fc92dbdeed0
--- /dev/null
+++ b/orc8r/cloud/deploy/orc8r_deployer/docker/README.md
@@ -0,0 +1,243 @@
+# Orcl
+
+Orcl is a Orchestrator CLI. It is used for managing Orc8r deployment. It provides following subcommands.
+
+- Configure
+- Certs
+- Install
+- Upgrade
+- Verify
+- Cleanup
+- Debug(perhaps in the future)
+
+[Image: image.png]Orcl is packaged within orc8r_deployer. Orc8r deployer is a docker image which contains all the necessary prerequisites to deploy orc8r. The only requirements for running orc8r_deployer is that the the host machine must have [docker engine installed](https://docs.docker.com/get-docker/).
+
+## Usage
+
+```
+./run_deployer runs the orc8r deployer container
+orc8r deployer contains scripts which enable user to configure, run prechecks
+install, upgrade, verify and cleanup an orc8r deployment
+Usage: run_deployer [-deploy-dir|-root-dir|-build|-h]
+options:
+-h Print this Help
+-deploy-dir deployment dir containing configs and secrets (mandatory)
+-root-dir magma root directory
+-build build the deployer container
+example: ./run_deployer -deploy-dir /tmp/orc8r_14_deployment
+```
+
+Deployment directory will be used to maintain the configs, secrets and also contain the deployment related files such as main.tf etc. It is important to use the same deployment directory during the upgrade so that the configuration variables can be reused.
+
+In the following section, we will discuss each of the orcl commands in detail.
+
+## Configure
+
+Every orc8r deployment relies on several configuration attributes. For e.g cluster_name attribute is used to identify the orc8r kubernetes cluster, orc8r_tag provides the image tag to be used during the deployment. Configure command enables user to easily configure the mandatory configs necessary for the deployment. It additionally provides the ability to also configure optional attributes through the ***set*** subcommand. Configure command also has subcommands like ***info*** to show all the possible configuration attributes and ***show*** to display the current configuration. Finally configure also contains a subcommand ***check*** which provides the ability to check if all mandatory configs needed by the deployment have been successfully configured.
+
+```
+# orcl configure --help
+Usage: orcl configure [OPTIONS] COMMAND [ARGS]...
+
+ Configure orc8r deployment variables
+
+Options:
+ -c, --component [infra|platform|service]
+ --help Show this message and exit.
+
+Commands:
+ check Check if all mandatory configs are present
+ info Display all possible config options in detail
+ set Set enables user to configure any configuration option.
+ show Display the current configuration
+```
+
+Note: Currently we don’t have the capability to sanitize the inputs. This might be a feature to be added later
+
+Configure command relies mainly on a meta file `vars.yml`. This file contains all deployment variables with their name, type, description, default value, whether it is a required or an optional attribute and finally the apps which rely on this configuration attribute.
+The configuration provided by the user is used to
+
+- set the aws configuration(specifically access_key, secret_key, region),
+- build terraform.tfvars.json(which is automatically loaded by terraform and provided to the root module)
+- build main.tf and vars.tf(to ensure that we set the vars in the root module for it to be correspondingly consumed by the orc8r and orc8r-app modules)
+
+For e.g.
+
+```
+module "orc8r" {
+ source = "/root/magma/orc8r/cloud/deploy/terraform/orc8r-aws"
+ cluster_name=var.cluster_name <-- generated from configured keys
+ cluster_version=var.cluster_version
+ orc8r_domain_name=var.orc8r_domain_name
+ region=var.region
+```
+
+## Certs
+
+Certs is a orcl command for managing certificates. Currently it has only one subcommand ***add*** which can be used to add application certs and self signed root certificates(optional).
+
+```
+# orcl certs --help
+Usage: orcl certs [OPTIONS] COMMAND [ARGS]...
+ Manage certs in orc8r deployment
+
+Options:
+ --help Show this message and exit.
+
+Commands:
+ add Add creates application and self signed(optional) certs
+```
+
+
+Certs relies on the orc8r configuration options being configured. Specifically it relies on `orc8r_domain_name` attribute to be configured.
+
+## Install
+
+Install command provides the ability to install an orc8r deployment based on provided configuration. Install command provides an optional ability to run prechecks prior to installation and also provides prechecks as a separate subcommand.
+
+```
+# orcl install --help
+Usage: orcl install [OPTIONS] COMMAND [ARGS]...
+
+ Deploy new instance of orc8r
+
+Options:
+ --help Show this message and exit.
+
+Commands:
+ precheck Performs various checks to ensure successful installation
+```
+
+Currently the installation process is dependent on terraform. Install command runs following subprocess commands
+
+```
+terraform init
+terraform apply -target=module.orc8r -auto-approve
+terraform apply -target=module.orc8r-app.null_resource.orc8r_seed_secrets -auto-approve
+terraform apply
+
+```
+
+Following prechecks are performed prior to the installation
+
+- Check if all mandatory configs are present
+- Check if all secret files are present
+- Check if we have atleast 3 availability zones in our deployment
+- Check if secrets manager is already configured with the orc8r secrets id
+- Check cloudwatch log group already exists
+- In case of elastic search deployment, check if AWSServiceRoleForAmazonElasticsearchService IAM role already exists
+- Check if orc8r deployment type is valid
+- Check if image tag specified is present in image repository
+- Check if helm chart specified is present in the helm repository
+
+## Upgrade
+
+Upgrade command provides the ability to install an orc8r deployment based on provided configuration. Upgrade command provides an optional ability to run prechecks prior to upgrade and also provides prechecks as a separate subcommand.
+**Note: it is important to use the same deployment directory which was used during install. This is mainly to ensure that the terraform state is available and also reuse the configuration variables**
+
+```
+# orcl upgrade --help
+Usage: orcl upgrade [OPTIONS] COMMAND [ARGS]...
+
+ Upgrade existing orc8r deployment
+
+Options:
+ --help Show this message and exit.
+
+Commands:
+ precheck Precheck runs various checks to ensure successful upgrade
+```
+
+Upgrade command runs the following upgrade command
+
+```
+terraform apply
+```
+
+Following prechecks are performed prior to the upgrade
+
+- Check if terraform state exists
+- Check if all mandatory configs are present
+- Check if we have atleast 3 availability zones in our deployment
+- Check if deployed EKS cluster version is greater than what’s specified in the configuration
+- In case of elastic search deployment, check if AWSServiceRoleForAmazonElasticsearchService IAM role already exists
+- Check if deployed RDS instance version is greater than what’s specified in the configuration
+- Check if image tag specified is present in image repository
+- Check if helm chart specified is present in the helm repository
+
+## Verify
+
+Verify command provides the ability to post deployment checks on orc8r.
+
+```
+Usage: orcl verify [OPTIONS] COMMAND [ARGS]...
+
+ Run post deployment checks on orc8r
+
+Options:
+ --help Show this message and exit.
+
+Commands:
+ sanity
+```
+
+Currently the subcommand ***sanity*** runs the following checks
+
+- Check if all kubernetes pods are healthy and dump the logs of unhealthy pods
+- Invoke get all networks API for generic and LTE networks(magma/v1/networks, magma/v1/lte) to ensure if the orchestrator and lte pods are working as expected
+
+## Cleanup
+
+Cleanup command provides the ability to cleanup all resources deployed during orc8r deployment
+
+```
+# orcl cleanup --help
+Usage: orcl cleanup [OPTIONS] COMMAND [ARGS]...
+
+ Removes resources deployed for orc8r
+
+Options:
+ --help Show this message and exit.
+
+Commands:
+ raw Individually cleans up resources deployed for orc8r
+```
+
+Cleanup runs
+
+```
+terraform destroy
+```
+
+to perform the cleanup. Unfortunately terraform cleanup hasn’t been very reliable in the past. So this command provides ability to also directly cleanup the underlying resources when the terraform destroy command fails. It is though the subcommand ***raw***
+
+```
+Usage: orcl cleanup raw [OPTIONS]
+
+ Individually cleans up resources deployed for orc8r
+
+Options:
+ --dryrun Show resources to be cleaned up during raw cleanup
+ --state TEXT Provide state file containing resource information e.g.
+ terraform.tfstate or terraform.tfstate.backup
+
+ --help Show this message and exit.
+```
+
+Currently the raw cleanup performs cleanup of the following
+
+- Orc8r cloudwatch log group
+- RDS instances
+- Elastic search instance.
+- EFS mount targets and volumes
+- EKS cluster
+- Autoscaling groups
+- Elastic load balancers
+- NAT gateways
+- Internet gateways
+- Subnets
+- VPC
+- Hosted records in hosted zone and hosted zone
+
+Note: The raw cleanup attempts to identify the above mentioned resources through `terraform show --json`
+Sometimes terraform destroy might cause state to be cleaned up and we have no way to identify the state to be cleaned up. So there is an optional knob to specify state. This can be used to provide terraform tfstate backup file to identify the resources to be cleaned up.
diff --git a/orc8r/cloud/deploy/orc8r_deployer/docker/root/config.yml b/orc8r/cloud/deploy/orc8r_deployer/docker/root/config.yml
new file mode 100644
index 000000000000..29bab4f3896e
--- /dev/null
+++ b/orc8r/cloud/deploy/orc8r_deployer/docker/root/config.yml
@@ -0,0 +1,16 @@
+project_dir: /root/project
+config_dir: /root/project/configs
+secret_dir: /root/project/secrets
+scripts_dir: /root/scripts
+tf_dir: /root/tf
+main_tf: /root/project/main.tf
+vars_tf: /root/project/vars.tf
+auto_tf: /root/project/terraform.tfvars.json
+data_dir: /root/data
+magma_root: /root/magma
+vars_definition: /root/data/vars.yml
+playbooks: /root/scripts/playbooks
+components:
+ - infra
+ - platform
+ - service
\ No newline at end of file
diff --git a/orc8r/cloud/deploy/orc8r_deployer/docker/root/data/vars.yml b/orc8r/cloud/deploy/orc8r_deployer/docker/root/data/vars.yml
new file mode 100644
index 000000000000..9979a207a431
--- /dev/null
+++ b/orc8r/cloud/deploy/orc8r_deployer/docker/root/data/vars.yml
@@ -0,0 +1,506 @@
+infra:
+ aws_access_key_id:
+ Description: AWS access key id.
+ Type: string
+ Required: true
+ ConfigApps:
+ -awscli
+ aws_secret_access_key:
+ Description: AWS access secret.
+ Type: string
+ Required: true
+ ConfigApps:
+ -awscli
+ region:
+ Description: AWS region to deploy Orchestrator components into. The chosen region must provide EKS.
+ Type: string
+ Required: true
+ ConfigApps:
+ -awscli
+ -tf
+ cluster_name:
+ Description: Name for the Orchestrator EKS cluster.
+ Type: string
+ Required: false
+ Default: "orc8r"
+ ConfigApps:
+ -tf
+ cluster_version:
+ Description: Kubernetes version for the EKS cluster
+ Type: string
+ Required: false
+ Default: "1.17"
+ ConfigApps:
+ -tf
+ eks_map_roles:
+ Description: EKS IAM role mapping. Note that by default, the creator of the cluster will be in the system:master group.
+ Type: list(object({rolearn = string, username = string, groups = list(string), }))
+ Required: false
+ ConfigApps:
+ -tf
+ eks_map_users:
+ Description: Additional IAM users to add to the aws-auth ConfigMap.
+ Type: list(object({userarn = string, username = string, groups = list(string)}))
+ Required: false
+ ConfigApps:
+ -tf
+ eks_worker_additional_policy_arns:
+ Description: Additional IAM policy ARNs to attach to EKS worker nodes.
+ Type: list(string)
+ Required: false
+ ConfigApps:
+ -tf
+ eks_worker_additional_sg_ids:
+ Description: Additional security group IDs to attach to EKS worker nodes.
+ Type: list(string)
+ Required: false
+ ConfigApps:
+ -tf
+ eks_worker_group_key:
+ Description: If specified, the worker nodes for EKS will use this EC2 keypair.
+ Type: string
+ Required: false
+ ConfigApps:
+ -tf
+ eks_worker_groups:
+ Description: Worker group configuration for EKS. Default value is 1 worker group consisting of 3 t3.large instances.
+ Type: any
+ Required: false
+ ConfigApps:
+ -tf
+ vpc_cidr:
+ Description: CIDR block for the VPC.
+ Type: string
+ Required: false
+ ConfigApps:
+ -tf
+ vpc_database_subnets:
+ Description: ' CIDR blocks for the VPC''s database subnets. '
+ Type: list(string)
+ Required: false
+ ConfigApps:
+ -tf
+ vpc_extra_tags:
+ Description: Tags to add to the VPC.
+ Type: map
+ Required: false
+ ConfigApps:
+ -tf
+ vpc_name:
+ Description: Name for the VPC that will contain all the Orchestrator components.
+ Type: string
+ Required: false
+ ConfigApps:
+ -tf
+ vpc_private_subnets:
+ Description: ' CIDR blocks for the VPC''s private subnets. '
+ Type: list(string)
+ Required: false
+ ConfigApps:
+ -tf
+ vpc_public_subnets:
+ Description: ' CIDR blocks for the VPC''s public subnets. '
+ Type: list(string)
+ Required: false
+ ConfigApps:
+ -tf
+ orc8r_domain_name:
+ Description: Base domain name for AWS Route 53 hosted zone.
+ Type: string
+ Required: true
+ ConfigApps:
+ -tf
+ secretsmanager_orc8r_secret:
+ Description: AWS Secret Manager secret to store Orchestrator secrets.
+ Type: string
+ Required: true
+ ConfigApps:
+ -tf
+
+platform:
+ deploy_elasticsearch:
+ Default: true
+ Description: Flag to deploy AWS Elasticsearch service as the datasink for aggregated logs.
+ Type: bool
+ Required: false
+ ConfigApps:
+ -tf
+ deploy_elasticsearch_service_linked_role:
+ Default: true
+ Description: ' Flag to deploy AWS Elasticsearch service linked role with cluster. If you''ve already created an ES service linked role for another cluster, you should set this to false. '
+ Type: bool
+ Required: false
+ ConfigApps:
+ -tf
+ efs_project_name:
+ Description: Project name for EFS file system
+ Type: string
+ Required: false
+ ConfigApps:
+ -tf
+ elasticsearch_az_count:
+ Default: 2
+ Description: AZ count for ES.
+ Type: number
+ Required: false
+ ConfigApps:
+ -tf
+ elasticsearch_dedicated_master_count:
+ Description: Number of dedicated ES master nodes.
+ Type: number
+ Required: false
+ ConfigApps:
+ -tf
+ elasticsearch_dedicated_master_enabled:
+ Description: Enable/disable dedicated master nodes for ES.
+ Type: bool
+ Required: false
+ ConfigApps:
+ -tf
+ elasticsearch_dedicated_master_type:
+ Description: Instance type for ES dedicated master nodes.
+ Type: string
+ Required: false
+ ConfigApps:
+ -tf
+ elasticsearch_domain_name:
+ Default: "orc8r-es"
+ Description: Name for the ES domain.
+ Type: string
+ Required: false
+ ConfigApps:
+ -tf
+ elasticsearch_domain_tags:
+ Description: Extra tags for the ES domain.
+ Type: map
+ Required: false
+ ConfigApps:
+ -tf
+ elasticsearch_ebs_enabled:
+ Default: true
+ Description: Use EBS for ES storage.
+ Type: bool
+ Required: false
+ ConfigApps:
+ -tf
+ elasticsearch_ebs_iops:
+ Description: IOPS for ES EBS volumes.
+ Type: number
+ Required: false
+ ConfigApps:
+ -tf
+ elasticsearch_ebs_volume_size:
+ Default: 32
+ Description: Size in GB to allocate for ES EBS data volumes.
+ Type: number
+ Required: false
+ ConfigApps:
+ -tf
+ elasticsearch_ebs_volume_type:
+ Default: gp2
+ Description: EBS volume type for ES data volumes.
+ Type: string
+ Required: false
+ ConfigApps:
+ -tf
+ elasticsearch_instance_count:
+ Default: 2
+ Description: Number of instances to allocate for ES domain.
+ Type: number
+ Required: false
+ ConfigApps:
+ -tf
+ elasticsearch_instance_type:
+ Default: "t2.medium.elasticsearch"
+ Description: AWS instance type for ES domain.
+ Type: string
+ Required: false
+ ConfigApps:
+ -tf
+ elasticsearch_version:
+ Default: "7.7"
+ Description: ES version for ES domain.
+ Type: string
+ Required: false
+ ConfigApps:
+ -tf
+ global_tags:
+ Description: n/a
+ Type: map
+ Required: false
+ ConfigApps:
+ -tf
+ orc8r_db_engine_version:
+ Default: "9.6.15"
+ Description: Postgres engine version for Orchestrator DB.
+ Type: string
+ Required: false
+ ConfigApps:
+ -tf
+ orc8r_db_identifier:
+ Default: "orc8rdb"
+ Description: Identifier for the RDS instance for Orchestrator.
+ Type: string
+ Required: false
+ ConfigApps:
+ -tf
+ orc8r_db_instance_class:
+ Description: RDS instance type for Orchestrator DB.
+ Type: string
+ Required: false
+ ConfigApps:
+ -tf
+ orc8r_db_name:
+ Description: DB name for Orchestrator RDS instance.
+ Type: string
+ Required: false
+ ConfigApps:
+ -tf
+ orc8r_db_password:
+ Description: Password for the Orchestrator DB.
+ Type: string
+ Required: true
+ ConfigApps:
+ -tf
+ orc8r_db_storage_gb:
+ Description: Capacity in GB to allocate for Orchestrator RDS instance.
+ Type: number
+ Required: false
+ ConfigApps:
+ -tf
+ orc8r_db_username:
+ Description: Username for default DB user for Orchestrator DB.
+ Type: string
+ Required: false
+ ConfigApps:
+ -tf
+service:
+ cwf_orc8r_chart_version:
+ Description: Version of the Orchestrator cwf module Helm chart to install.
+ Type: string
+ Required: false
+ ConfigApps:
+ -tf
+ Default: "0.2.1"
+ deploy_nms:
+ Description: Flag to deploy NMS.
+ Type: bool
+ Required: false
+ ConfigApps:
+ -tf
+ deploy_openvpn:
+ Description: Flag to deploy OpenVPN server into cluster. This is useful if you want to remotely access AGWs.
+ Type: bool
+ Required: false
+ ConfigApps:
+ -tf
+ docker_pass:
+ Description: Docker registry password.
+ Type: string
+ Required: true
+ ConfigApps:
+ -tf
+ docker_registry:
+ Description: Docker registry to pull Orchestrator containers from.
+ Type: string
+ Required: true
+ ConfigApps:
+ -tf
+ docker_user:
+ Description: Docker username to login to registry with.
+ Type: string
+ Required: true
+ ConfigApps:
+ -tf
+ efs_file_system_id:
+ Description: ID of the EFS file system to use for K8s persistent volumes.
+ Type: string
+ Required: false
+ ConfigApps:
+ -tf
+ efs_provisioner_role_arn:
+ Description: ARN of the IAM role for the EFS provisioner.
+ Type: string
+ Required: false
+ ConfigApps:
+ -tf
+ eks_cluster_id:
+ Description: EKS cluster ID for the K8s cluster.
+ Type: string
+ Required: false
+ ConfigApps:
+ -tf
+ elasticsearch_endpoint:
+ Description: Endpoint of the Elasticsearch datasink for aggregated logs and events.
+ Type: string
+ Required: false
+ ConfigApps:
+ -tf
+ elasticsearch_retention_days:
+ Description: Retention period in days of Elasticsearch indices.
+ Type: number
+ Required: false
+ ConfigApps:
+ -tf
+ existing_tiller_service_account_name:
+ Description: Name of existing Tiller service account to use for Helm.
+ Type: string
+ Required: false
+ ConfigApps:
+ -tf
+ external_dns_role_arn:
+ Description: IAM role ARN for ExternalDNS.
+ Type: string
+ Required: false
+ ConfigApps:
+ -tf
+ fbinternal_orc8r_chart_version:
+ Description: Version of the Orchestrator fbinternal module Helm chart to install.
+ Type: string
+ Required: false
+ ConfigApps:
+ -tf
+ Default: "0.2.1"
+ feg_orc8r_chart_version:
+ Description: Version of the Orchestrator feg module Helm chart to install.
+ Type: string
+ Required: false
+ ConfigApps:
+ -tf
+ Default: "0.2.2"
+ helm_deployment_name:
+ Description: Name for the Helm release.
+ Type: string
+ Required: false
+ ConfigApps:
+ -tf
+ helm_pass:
+ Description: Helm repository password.
+ Type: string
+ Required: true
+ ConfigApps:
+ -tf
+ helm_repo:
+ Description: Helm repository URL for Orchestrator charts.
+ Type: string
+ Required: true
+ ConfigApps:
+ -tf
+ helm_user:
+ Description: Helm username to login to repository with.
+ Type: string
+ Required: true
+ ConfigApps:
+ -tf
+ install_tiller:
+ Description: Install Tiller in the cluster or not.
+ Type: bool
+ Required: false
+ ConfigApps:
+ -tf
+ lte_orc8r_chart_version:
+ Description: Version of the Orchestrator lte module Helm chart to install.
+ Type: string
+ Required: false
+ ConfigApps:
+ -tf
+ Default: "0.2.4"
+ monitoring_kubernetes_namespace:
+ Description: K8s namespace to install Orchestrator monitoring components into.
+ Type: string
+ Required: false
+ ConfigApps:
+ -tf
+ orc8r_chart_version:
+ Description: Version of the core Orchestrator Helm chart to install.
+ Type: string
+ Required: false
+ ConfigApps:
+ -tf
+ Default: "1.5.19"
+ orc8r_controller_replicas:
+ Description: Replica count for Orchestrator controller pods.
+ Type: number
+ Required: false
+ ConfigApps:
+ -tf
+ orc8r_db_port:
+ Description: DB port for Orchestrator database connection.
+ Type: number
+ Required: false
+ ConfigApps:
+ -tf
+ orc8r_deployment_type:
+ Description: Deployment type of Orchestrator (fwa, federated fwa(ffwa), all).
+ Type: string
+ Required: true
+ ConfigApps:
+ -tf
+ orc8r_kubernetes_namespace:
+ Description: K8s namespace to install main Orchestrator components into.
+ Type: string
+ Required: false
+ ConfigApps:
+ -tf
+ orc8r_proxy_replicas:
+ Description: Replica count for Orchestrator proxy pods.
+ Type: number
+ Required: false
+ ConfigApps:
+ -tf
+ orc8r_route53_zone_id:
+ Description: Route53 zone ID of Orchestrator domain name for ExternalDNS.
+ Type: string
+ Required: false
+ ConfigApps:
+ -tf
+ orc8r_tag:
+ Description: Image tag for Orchestrator components.
+ Type: string
+ Required: true
+ ConfigApps:
+ -tf
+ secretsmanager_orc8r_name:
+ Description: Name of the AWS Secrets Manager secret where Orchestrator deployment secrets will be stored.
+ Type: string
+ Required: false
+ ConfigApps:
+ -tf
+ seed_certs_dir:
+ Description: Directory on LOCAL disk where Orchestrator certificates are stored to seed Secrets Manager values. Home directory and env vars will be expanded.
+ Type: string
+ Required: false
+ ConfigApps:
+ -tf
+ state_backend:
+ Description: State backend for terraform (e.g. s3, local).
+ Type: string
+ Required: false
+ ConfigApps:
+ -tf
+ state_config:
+ Description: Optional config for state backend. The object type will depend on your backend.
+ Type: any
+ Required: false
+ ConfigApps:
+ -tf
+ tiller_namespace:
+ Description: Namespace where Tiller is installed or should be installed into.
+ Type: string
+ Required: false
+ ConfigApps:
+ -tf
+ wifi_orc8r_chart_version:
+ Description: Version of the Orchestrator wifi module Helm chart to install.
+ Type: string
+ Required: false
+ ConfigApps:
+ -tf
+ Default: "0.2.1"
+ seed_certs_dir:
+ Description: Directory on LOCAL disk where Orchestrator certificates are stored to seed Secrets Manager values. Home directory and env vars will be expanded.
+ Type : string
+ Required: false
+ ConfigApps:
+ -tf
+ Default : "/root/project/secrets"
\ No newline at end of file
diff --git a/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/cli/__init__.py b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/cli/__init__.py
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/cli/certs.py b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/cli/certs.py
new file mode 100644
index 000000000000..ce6b124e5301
--- /dev/null
+++ b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/cli/certs.py
@@ -0,0 +1,55 @@
+"""
+Copyright 2021 The Magma Authors.
+
+This source code is licensed under the BSD-style license found in the
+LICENSE file in the root directory of this source tree.
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+import click
+
+from .common import (
+ run_command,
+ run_playbook,
+ print_error_msg,
+ print_success_msg)
+
+@click.group()
+@click.pass_context
+def certs(ctx):
+ """
+ Manage certs in orc8r deployment
+ """
+ pass
+
+@certs.command()
+@click.pass_context
+@click.option('--self-signed', is_flag=True)
+def add(ctx, self_signed):
+ """
+ Add creates application and self signed(optional) certs
+ """
+ if self_signed:
+ run_playbook([
+ "ansible-playbook",
+ "-v",
+ "-e",
+ "@/root/config.yml",
+ "-t",
+ "addcerts",
+ "%s/certs.yml" % ctx.obj["playbooks"]])
+ else:
+ run_playbook([
+ "ansible-playbook",
+ "-v",
+ "-e",
+ "@/root/config.yml",
+ "-t",
+ "addcerts",
+ "--skip-tags",
+ "self_signed",
+ "%s/certs.yml" % ctx.obj["playbooks"]])
\ No newline at end of file
diff --git a/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/cli/cleanup.py b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/cli/cleanup.py
new file mode 100644
index 000000000000..f009db2c4a82
--- /dev/null
+++ b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/cli/cleanup.py
@@ -0,0 +1,96 @@
+"""
+Copyright 2021 The Magma Authors.
+
+This source code is licensed under the BSD-style license found in the
+LICENSE file in the root directory of this source tree.
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+import os
+import sys
+import json
+
+import click
+from boto3 import Session
+
+from .common import (
+ run_command,
+ run_playbook,
+ print_error_msg,
+ print_success_msg)
+
+def setup_aws_creds():
+ session = Session()
+ creds = session.get_credentials()
+ if not creds:
+ print_error_msg('''
+AWS credentials not configured.
+configure through awscli or through orcl
+orcl configure set -k aws_access_key_id -v
+orcl configure set -k aws_secret_access_key -v
+orcl configure set -k region -v
+''')
+ sys.exit(1)
+
+ frozen_creds = creds.get_frozen_credentials()
+ os.environ["AWS_ACCESS_KEY_ID"] = frozen_creds.access_key
+ os.environ["AWS_SECRET_ACCESS_KEY"] = frozen_creds.secret_key
+
+
+@click.group(invoke_without_command=True)
+@click.pass_context
+def cleanup(ctx):
+ """
+ Removes resources deployed for orc8r
+ """
+ tf_destroy = [ "terraform", "destroy", "-auto-approve"]
+
+ if ctx.invoked_subcommand is None:
+ cmd = " ".join(tf_destroy)
+ click.echo(f"Following commands will be run during cleanup\n{cmd}")
+ click.confirm('Do you want to continue with cleanup?', abort=True)
+ click.echo(f"Running {cmd}")
+ rc = run_command(tf_destroy)
+ if rc != 0:
+ print_error_msg("Destroy Failed!!! Attempt cleaning up individual resources using 'orcl cleanup raw' subcommand")
+ return
+
+@cleanup.command()
+@click.pass_context
+@click.option('--dryrun', default=False, is_flag=True, help='Show resources to be cleaned up during raw cleanup')
+@click.option('--state', help='Provide state file containing resource information e.g. terraform.tfstate or terraform.tfstate.backup')
+@click.option('--values', multiple=True, help='Key value pairs. for e.g. cluster_name,orc8r. Can be used multiple times')
+def raw(ctx, dryrun, state, values):
+ """
+ Individually cleans up resources deployed for orc8r
+ """
+ if state:
+ ctx.obj['cleanup_state'] = state
+
+ # add additional items
+ for config_items in values:
+ k, v = config_items.split(",")
+ ctx.obj[k] = v
+
+ extra_vars = json.dumps(ctx.obj)
+ cleanup_playbook = "%s/cleanup.yml" % ctx.obj["playbooks"]
+ playbook_args = [ "ansible-playbook", "-v", "-e", extra_vars]
+
+ # Few boto dependent modules in ansible require these values to be
+ # setup as environment variables. Hence setting these up.
+ setup_aws_creds()
+
+ if dryrun:
+ tag_args = ["-t", "cleanup_dryrun"]
+ else:
+ tag_args = ["-t", "cleanup"]
+
+ rc = run_playbook(playbook_args + tag_args + [cleanup_playbook])
+ if rc != 0:
+ print_error_msg("Failed cleaning up resources!!!")
+ sys.exit(1)
+ print_success_msg("Successfully cleaned up underlying resources")
\ No newline at end of file
diff --git a/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/cli/common.py b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/cli/common.py
new file mode 100644
index 000000000000..a72b72235725
--- /dev/null
+++ b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/cli/common.py
@@ -0,0 +1,40 @@
+"""
+Copyright 2021 The Magma Authors.
+
+This source code is licensed under the BSD-style license found in the
+LICENSE file in the root directory of this source tree.
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+import subprocess
+
+import click
+from ansible.cli.playbook import PlaybookCLI
+
+def run_playbook(args):
+ pb_cli = PlaybookCLI(args)
+ pb_cli.parse()
+ return pb_cli.run()
+
+def run_command(cmd):
+ with subprocess.Popen(cmd, stdout=subprocess.PIPE) as p:
+ for output in p.stdout:
+ click.echo(output, nl=False)
+ return p.wait()
+ return 1
+
+def print_error_msg(msg):
+ click.echo(click.style(msg, fg='red'))
+
+def print_success_msg(msg):
+ click.echo(click.style(msg, fg='green'))
+
+def print_warning_msg(msg):
+ click.echo(click.style(msg, fg='yellow'))
+
+def print_info_msg(msg):
+ click.echo(click.style(msg, fg='blue'))
\ No newline at end of file
diff --git a/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/cli/configlib.py b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/cli/configlib.py
new file mode 100644
index 000000000000..c843618f92f5
--- /dev/null
+++ b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/cli/configlib.py
@@ -0,0 +1,223 @@
+"""
+Copyright 2021 The Magma Authors.
+
+This source code is licensed under the BSD-style license found in the
+LICENSE file in the root directory of this source tree.
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+
+import os
+import json
+import yaml
+from subprocess import check_call, CalledProcessError
+
+from jinja2 import Environment, FileSystemLoader
+from prettytable import PrettyTable
+import click
+
+def get_input(text, default_val):
+ if default_val:
+ resp = click.prompt(text, default=default_val)
+ else:
+ resp = click.prompt(text, default=default_val, show_default=False)
+
+ # strip any quotes
+ resp = resp.strip("\'").strip("\"")
+ return resp
+
+def get_json(fn: str) -> dict:
+ try:
+ with open(fn) as f:
+ return json.load(f)
+ except OSError:
+ pass
+ return {}
+
+def put_json(fn: str, cfgs: dict):
+ with open(fn, 'w') as outfile:
+ json.dump(cfgs, outfile)
+
+def add_pretty_table(fields, items):
+ table = PrettyTable()
+ table.field_names = fields
+ for field in fields:
+ table.align[field] = 'l'
+
+ for item in items:
+ table.add_row(item)
+ return table
+
+def render_j2_template(src_dir, dst_fn, cfg):
+ env = Environment(loader=FileSystemLoader(searchpath=src_dir))
+ fn = os.path.basename(dst_fn)
+ template = env.get_template(f'{fn}.j2')
+ try:
+ with open(dst_fn, "w") as f:
+ f.write(template.render(cfg=cfg))
+ except Exception as err:
+ click.echo(f"Error: {fn} rendering {err!r} file ")
+
+class ConfigManager(object):
+ '''
+ ConfigManager manages the orcl configuration. It reads the variable
+ definitions during init and uses the information parsed to configure
+ the various component attributes.
+ Currently the variables are used to configure aws cli and
+ terraform.
+ '''
+ def _get_config_fn(self, component: str):
+ config_dir = self.constants['config_dir']
+ return f"{config_dir}/{component}.tfvars.json"
+
+ def set(self, component: str, key: str, value: str):
+ click.echo(f"Setting key {key} value {value} for component {component}")
+ cfgs = get_json(self._get_config_fn(component))
+ config_vars = self.config_vars[component]
+
+ if not config_vars.get(key):
+ click.echo("not a valid key")
+ return
+ cfgs[key] = value
+
+ self._configure_aws(component, cfgs)
+ self._configure_tf(component, cfgs)
+ put_json(self._get_config_fn(component), cfgs)
+
+ def configure(self, component: str):
+ click.echo(click.style(f"\nConfiguring {component} deployment variables ", underline=True))
+ cfgs = self.configs[component]
+ # TODO: use a different yaml loader to ensure we load inorder
+ # sort the variables to group the inputs together
+ config_vars = self.config_vars[component].items()
+ for config_key, config_info in sorted(config_vars, key=lambda s: s[0]):
+ config_description = config_info.get('Description', config_key).strip('.')
+ defaultValue = config_info.get('Default')
+ # add defaults to the json configs to ensure we can run prechecks
+ if defaultValue:
+ cfgs[config_key] = defaultValue
+ continue
+
+ if not config_info['Required']:
+ continue
+
+ v = cfgs.get(config_key)
+ if v:
+ inp = get_input(f"{config_key}({config_description})" , v)
+ else:
+ inp = get_input(f"{config_key}({config_description})" , v)
+
+ # strip quotes from input
+ if inp:
+ cfgs[config_key] = inp
+ else:
+ if v is None:
+ if click.confirm("press 'y' to set empty string and "
+ "'n' to skip", prompt_suffix=': '):
+ cfgs[config_key] = ""
+
+ self.configs[component] = cfgs
+ self._configure_aws(component, cfgs)
+ self._configure_tf(component, cfgs)
+ put_json(self._get_config_fn(component), cfgs)
+
+ def _configure_aws(self, component: str, cfgs: dict):
+ ''' configures aws cli with configuration '''
+ for k, v in cfgs.items():
+ if k in self.aws_vars:
+ check_call(["aws", "configure", "set", k, v])
+
+ def _configure_tf(self, component: str, cfgs: dict):
+ ''' updates the terraform auto configuration and main.tf '''
+ auto_tf = self.constants['auto_tf']
+ auto_cfgs = get_json(auto_tf)
+ for k, v in cfgs.items():
+ if k in self.tf_vars:
+ auto_cfgs[k] = v
+ put_json(auto_tf, auto_cfgs)
+
+ # render main.tf with terraform variables alone
+ tf_cfgs = {}
+ for component in self.configs:
+ tf_cfgs[component] = {}
+ for k, v in self.configs[component].items():
+ if k in self.tf_vars:
+ tf_cfgs[component][k] = v
+
+ render_j2_template(
+ self.constants['tf_dir'],
+ self.constants['main_tf'],
+ tf_cfgs)
+ render_j2_template(
+ self.constants['tf_dir'],
+ self.constants['vars_tf'],
+ self.tf_vars)
+
+
+ def check(self, component: str) -> bool:
+ ''' check if all mandatory options of a specific component is set '''
+ cfgs = self.configs[component]
+ valid = True
+ missing_cfgs = []
+ for k, v in self.config_vars[component].items():
+ if v['Required'] and cfgs.get(k) is None:
+ missing_cfgs.append(k)
+ valid = False
+ if missing_cfgs:
+ click.echo(f"Missing {missing_cfgs!r} configs for {component} component")
+ else:
+ click.echo(f"All mandatory configs for {component} has been configured")
+ return valid
+
+ def info(self, component: str):
+ ''' pretty click.echo vars yml '''
+ click.echo (f"{component} Configuration Options")
+ fields = ["Name", "Description", "Type", "Required", "Used By"]
+ items = []
+ for k, v in self.config_vars[component].items():
+ items.append([
+ k,
+ v["Description"],
+ v["Type"],
+ v["Required"],
+ v["ConfigApps"]
+ ])
+ click.echo(add_pretty_table(fields, items))
+
+ def show(self, component: str):
+ ''' pretty click.echo existing configuration '''
+ click.echo (f"{component} Configuration")
+ items = [[k, v] for k, v in self.configs[component].items()]
+ fields = ["Name", "Configuration"]
+
+ click.echo(add_pretty_table(fields, items))
+
+ def __init__(self, constants: dict):
+ self.config_vars = {}
+ self.configs = {}
+ self.tf_vars = set()
+ self.aws_vars = set()
+ self.constants = constants
+ vars_fn = constants['vars_definition']
+ try:
+ with open(vars_fn) as f:
+ self.config_vars = yaml.load(f, Loader=yaml.FullLoader)
+ except OSError:
+ click.echo(f"Failed opening vars file {vars_fn}")
+
+ # read all configs
+ for component in constants['components']:
+ try:
+ fn = self._get_config_fn(component)
+ self.configs[component] = get_json(fn)
+ for k, v in self.config_vars[component].items():
+ if 'tf' in v["ConfigApps"]:
+ self.tf_vars.add(k)
+ if 'awscli' in v["ConfigApps"]:
+ self.aws_vars.add(k)
+ except OSError:
+ pass
diff --git a/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/cli/configlib_test.py b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/cli/configlib_test.py
new file mode 100644
index 000000000000..df24e3ade951
--- /dev/null
+++ b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/cli/configlib_test.py
@@ -0,0 +1,242 @@
+"""
+Copyright 2021 The Magma Authors.
+
+This source code is licensed under the BSD-style license found in the
+LICENSE file in the root directory of this source tree.
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+
+import os
+import shutil
+import yaml
+from tempfile import mkdtemp
+
+from unittest import TestCase, main
+from unittest.mock import patch, Mock
+
+import configlib
+
+
+class TestConfigManager(TestCase):
+ def setUp(self):
+ self.root_dir = mkdtemp()
+ self.constants = {
+ 'project_dir': self.root_dir,
+ 'config_dir': '%s/configs' % self.root_dir,
+ 'vars_definition': '%s/vars.yml' % self.root_dir,
+ 'components': ['infra', 'platform', 'service'],
+ 'auto_tf': self.root_dir + '/terraform.tfvars.json',
+ 'tf_dir': self.root_dir,
+ 'main_tf': self.root_dir + '/main.tf',
+ 'vars_tf': self.root_dir + '/vars.tf'
+ }
+ # add config directory
+ os.makedirs(self.constants["config_dir"])
+ test_vars = {
+ "infra": {
+ "aws_access_key_id": {
+ "Required": True,
+ "ConfigApps": ["awscli"]
+ },
+ "aws_secret_access_key": {
+ "Required": True,
+ "ConfigApps": ["awscli"]
+ },
+ "cluster_name": {
+ "Required": False,
+ "ConfigApps": ["tf"]
+ },
+ "secretsmanager_orc8r_secret": {
+ "Required": True,
+ "ConfigApps": ["tf"]
+ }
+ },
+ "platform": {
+ "deploy_elastic": {
+ "Required": False,
+ "ConfigApps": ["tf"]
+ },
+ "nms_db_password": {
+ "Required": True,
+ "ConfigApps": ["tf"]
+ }
+ },
+ "service": {
+ "lte_orc8r_chart_version": {
+ "Required": False,
+ "Default": "0.2.4",
+ "ConfigApps": ["tf"]
+ },
+ }
+ }
+ with open(self.constants['vars_definition'], 'w') as f:
+ yaml.dump(test_vars, f)
+
+ # write a simple jinja template file
+ jinja_template = (
+'''
+{% for k in cfg['infra'] %}
+{{k}}=var.{{k}}{% endfor %}
+''')
+ with open(self.constants['tf_dir'] + '/main.tf.j2', 'w') as f:
+ f.write(jinja_template)
+
+ jinja_template = (
+'''
+{% for k in cfg %}
+variable "{{k}}" {}{% endfor %}
+''')
+ with open(self.constants['tf_dir'] + '/vars.tf.j2', 'w') as f:
+ f.write(jinja_template)
+
+ def tearDown(self):
+ try:
+ shutil.rmtree(self.root_dir)
+ except:
+ pass
+
+ @patch("configlib.get_input")
+ @patch("configlib.check_call")
+ def test_configure_sanity(self, mock_check_call, mock_get_input):
+ mock_vals = {
+ 'aws_access_key_id': 'foo',
+ 'aws_secret_access_key': 'bar',
+ 'secretsmanager_orc8r_secret': 'jar',
+ }
+ mock_get_input.side_effect = [
+ mock_vals['aws_access_key_id'],
+ mock_vals['aws_secret_access_key'],
+ mock_vals['secretsmanager_orc8r_secret'],
+ ]
+ # verify if components tfvars json is created
+ mgr = configlib.ConfigManager(self.constants)
+ mgr.configure('infra')
+
+ # verify if configs are set in infra tfvars json
+ fn = "%s/infra.tfvars.json" % self.constants['config_dir']
+ cfg = configlib.get_json(fn)
+ self.assertEqual(len(cfg.keys()), 3)
+ self.assertEqual(cfg['aws_access_key_id'], "foo")
+ self.assertEqual(cfg['aws_secret_access_key'], "bar")
+ self.assertEqual(cfg['secretsmanager_orc8r_secret'], "jar")
+
+ # check if aws configs are set
+ aws_config_cmd = ['aws', 'configure', 'set']
+ mock_check_call.assert_any_call(
+ aws_config_cmd + ['aws_access_key_id', 'foo'])
+ mock_check_call.assert_any_call(
+ aws_config_cmd + ['aws_secret_access_key', 'bar'])
+
+ # verify that platform tfvars json file isn't present
+ fn = "%s/platform.tfvars.json" % self.constants['config_dir']
+ self.assertEqual(os.path.isfile(fn), False)
+
+ # reset mocks
+ mock_get_input.reset_mock()
+ mock_check_call.reset_mock()
+
+ mock_vals = {
+ 'nms_db_password': 'foo',
+ }
+ mock_get_input.side_effect = [
+ mock_vals['nms_db_password'],
+ ]
+
+ # configure platform
+ mgr.configure('platform')
+
+ # verify that no aws call was invoked
+ self.assertEqual(mock_check_call.call_count, 0)
+
+ # check if we only invoked input for nms_db_password
+ self.assertEqual(mock_get_input.call_count, 1)
+ fn = "%s/platform.tfvars.json" % self.constants['config_dir']
+ cfg = configlib.get_json(fn)
+ self.assertEqual(len(cfg.keys()), 1)
+ self.assertEqual(cfg['nms_db_password'], "foo")
+
+
+ # verify that service tfvars json file isn't present
+ fn = "%s/service.tfvars.json" % self.constants['config_dir']
+ self.assertEqual(os.path.isfile(fn), False)
+
+ # reset mocks
+ mock_get_input.reset_mock()
+ mock_check_call.reset_mock()
+
+ # configure service
+ mgr.configure('service')
+
+ # verify that no input or aws call was invoked
+ self.assertEqual(mock_check_call.call_count, 0)
+ self.assertEqual(mock_get_input.call_count, 0)
+
+ fn = "%s/service.tfvars.json" % self.constants['config_dir']
+ cfg = configlib.get_json(fn)
+ # verify that default value was set
+ self.assertEqual(len(cfg.keys()), 1)
+ self.assertEqual(cfg['lte_orc8r_chart_version'], "0.2.4")
+
+ # finally verify if all configs required by tf is present
+ cfg = configlib.get_json(self.constants['auto_tf'])
+ self.assertEqual(len(cfg.keys()), 3)
+ self.assertEqual(cfg['secretsmanager_orc8r_secret'], "jar")
+ self.assertEqual(cfg['nms_db_password'], "foo")
+ self.assertEqual(cfg['lte_orc8r_chart_version'], "0.2.4")
+
+ # verify if jinja template has been rendered accordingly
+ with open(self.constants['main_tf']) as f:
+ jinja_cfg = dict(ln.split('=') for ln in f.readlines() if ln.strip())
+
+ # all infra terraform keys should be present in the jinja template
+ self.assertEqual(
+ set(jinja_cfg.keys()),
+ set(['secretsmanager_orc8r_secret']))
+
+ # variable tf is of the form variable "var_name" {}
+ # get the middle element and remove the quotes
+ with open(self.constants['vars_tf']) as f:
+ jinja_cfg = [ln.split()[1][1:-1] for ln in f.readlines() if ln.strip()]
+
+ # all infra terraform keys should be present in the jinja template
+ self.assertEqual(set(jinja_cfg), set(mgr.tf_vars))
+
+ @patch("configlib.get_input")
+ @patch("configlib.check_call")
+ def test_configure_set(self, mock_check_call, mock_get_input):
+ mock_vals = {
+ 'nms_db_password': 'foo',
+ }
+ mock_get_input.side_effect = [
+ mock_vals['nms_db_password'],
+ ]
+
+ # configure platform
+ mgr = configlib.ConfigManager(self.constants)
+ mgr.configure('platform')
+
+ # check if we only invoked input for nms_db_password
+ self.assertEqual(mock_get_input.call_count, 1)
+ fn = "%s/platform.tfvars.json" % self.constants['config_dir']
+ cfg = configlib.get_json(fn)
+ self.assertEqual(len(cfg.keys()), 1)
+ self.assertEqual(cfg['nms_db_password'], "foo")
+
+ mgr.set('platform', 'deploy_elastic', 'true')
+ cfg = configlib.get_json(fn)
+ self.assertEqual(len(cfg.keys()), 2)
+ self.assertEqual(cfg['deploy_elastic'], "true")
+
+ # finally verify if all configs required by tf is present
+ cfg = configlib.get_json(self.constants['auto_tf'])
+ self.assertEqual(len(cfg.keys()), 2)
+ self.assertEqual(cfg['nms_db_password'], "foo")
+ self.assertEqual(cfg['deploy_elastic'], "true")
+
+if __name__ == '__main__':
+ main()
\ No newline at end of file
diff --git a/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/cli/configure.py b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/cli/configure.py
new file mode 100644
index 000000000000..115c08bea10d
--- /dev/null
+++ b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/cli/configure.py
@@ -0,0 +1,93 @@
+"""
+Copyright 2021 The Magma Authors.
+
+This source code is licensed under the BSD-style license found in the
+LICENSE file in the root directory of this source tree.
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+import sys
+
+import click
+
+from .configlib import ConfigManager
+
+def get_component_choices():
+ return ['infra', 'platform', 'service']
+
+@click.group(invoke_without_command=True)
+@click.option('-c', '--component',
+ type=click.Choice(get_component_choices()),
+ multiple=True,
+ default=get_component_choices())
+@click.pass_context
+def configure(ctx, component):
+ """
+ Configure orc8r deployment variables
+ """
+ if ctx.invoked_subcommand is None:
+ mgr = ConfigManager(ctx.obj)
+ for c in component:
+ mgr.configure(c)
+
+@configure.command()
+@click.pass_context
+@click.option('-c', '--component',
+ type=click.Choice(get_component_choices()),
+ multiple=True,
+ default=get_component_choices())
+def show(ctx, component):
+ """
+ Display the current configuration
+ """
+ mgr = ConfigManager(ctx.obj)
+ for c in component:
+ mgr.show(c)
+
+@configure.command()
+@click.option('-c', '--component',
+ type=click.Choice(get_component_choices()),
+ multiple=True,
+ default=get_component_choices())
+@click.pass_context
+def info(ctx, component):
+ """
+ Display all possible config options in detail
+ """
+ mgr = ConfigManager(ctx.obj)
+ for c in component:
+ mgr.info(c)
+
+@configure.command()
+@click.option('-c', '--component',
+ type=click.Choice(get_component_choices()),
+ multiple=True,
+ default=get_component_choices())
+@click.pass_context
+def check(ctx, component):
+ """
+ Check if all mandatory configs are present
+ """
+ mgr = ConfigManager(ctx.obj)
+ valid = True
+ for c in component:
+ valid = mgr.check(c)
+ if not valid:
+ sys.exit(1)
+
+@configure.command()
+@click.option('-c', '--component',
+ type=click.Choice(get_component_choices()),
+ prompt='select component')
+@click.option('-k', '--key', prompt='name of the variable')
+@click.option('-v', '--value', prompt='value of the variable')
+@click.pass_context
+def set(ctx, component, key, value):
+ """
+ Set a specific configuration attribute
+ """
+ ConfigManager(ctx.obj).set(component, key, value)
\ No newline at end of file
diff --git a/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/cli/install.py b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/cli/install.py
new file mode 100644
index 000000000000..1f7130b49a06
--- /dev/null
+++ b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/cli/install.py
@@ -0,0 +1,91 @@
+"""
+Copyright 2021 The Magma Authors.
+
+This source code is licensed under the BSD-style license found in the
+LICENSE file in the root directory of this source tree.
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+import os
+import sys
+import glob
+
+import click
+
+from .common import (
+ run_command,
+ run_playbook,
+ print_error_msg,
+ print_success_msg,
+ print_warning_msg,
+ print_info_msg,
+)
+
+@click.group(invoke_without_command=True)
+@click.pass_context
+def install(ctx):
+ """
+ Deploy new instance of orc8r
+ """
+ constants = ctx.obj
+
+ tf_init = ["terraform", "init"]
+ tf_orc8r = [ "terraform", "apply", "-target=module.orc8r", "-auto-approve"]
+ tf_secrets = [ "terraform", "apply", "-target=module.orc8r-app.null_resource.orc8r_seed_secrets", "-auto-approve"]
+ tf_orc8r_app = [ "terraform", "apply", "-auto-approve"]
+
+ if ctx.invoked_subcommand is None:
+ if click.confirm('Do you want to run installation prechecks?'):
+ ctx.invoke(precheck)
+ else:
+ print_warning_msg(f"Skipping installation prechecks")
+
+ for tf_cmd in [tf_init, tf_orc8r, tf_secrets, tf_orc8r_app]:
+ cmd = " ".join(tf_cmd)
+ if click.confirm(f'Do you want to continue with {cmd}?'):
+ rc = run_command(tf_cmd)
+ if rc != 0:
+ print_error_msg(f"Install failed when running {cmd} !!!")
+ return
+
+ # set the kubectl after bringing up the infra
+ if tf_cmd == tf_orc8r or tf_orc8r_app:
+ kubeconfigs = glob.glob(constants['project_dir'] + "/kubeconfig_*")
+ if len(kubeconfigs) != 1:
+ if len(kubeconfigs) == 0:
+ print_success_msg('No kubeconfig found!!!')
+ else:
+ print_error_msg("multiple kubeconfigs found %s!!!" % repr(kubeconfigs))
+ return
+ kubeconfig = kubeconfigs[0]
+ os.environ['KUBECONFIG'] = kubeconfig
+ print_info_msg(f'For accessing kubernetes cluster, set `export KUBECONFIG={kubeconfig}`')
+ print_success_msg(f"Command {cmd} ran successfully")
+
+ else:
+ print_warning_msg(f"Skipping Command {cmd}")
+
+
+
+@install.command()
+@click.pass_context
+def precheck(ctx):
+ """
+ Performs various checks to ensure successful installation
+ """
+ rc = run_playbook([
+ "ansible-playbook",
+ "-v",
+ "-e",
+ "@/root/config.yml",
+ "-t",
+ "install_precheck",
+ "%s/main.yml" % ctx.obj["playbooks"]])
+ if rc != 0:
+ print_error_msg("Install prechecks failed!!!")
+ sys.exit(1)
+ print_success_msg("Install prechecks ran successfully")
diff --git a/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/cli/orcl.py b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/cli/orcl.py
new file mode 100755
index 000000000000..d525804e2364
--- /dev/null
+++ b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/cli/orcl.py
@@ -0,0 +1,62 @@
+"""
+Copyright 2021 The Magma Authors.
+
+This source code is licensed under the BSD-style license found in the
+LICENSE file in the root directory of this source tree.
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+from typing import List
+import os
+import sys
+import argparse
+import subprocess
+import pprint
+import yaml
+import pathlib
+
+import click
+
+from .configure import configure
+from .install import install
+from .upgrade import upgrade
+from .verify import verify
+from .certs import certs
+from .cleanup import cleanup
+
+def init():
+ constants = None
+ try:
+ with open("/root/config.yml") as f:
+ constants = yaml.load(f, Loader=yaml.FullLoader)
+ except OSError:
+ click.echo("Failed opening config.yml file")
+
+ dirnames = (constants["config_dir"], constants["secret_dir"])
+ for dirname in dirnames:
+ try:
+ pathlib.Path(dirname).mkdir(parents=True, exist_ok=True)
+ except OSError as error:
+ click.echo(f"failed creating dir {dirname} error {error}")
+ sys.exit(1)
+ return constants
+
+@click.group()
+@click.version_option()
+@click.pass_context
+def cli(ctx):
+ """
+ Orchestrator Deployment CLI
+ """
+ ctx.obj = init()
+
+cli.add_command(configure)
+cli.add_command(certs)
+cli.add_command(install)
+cli.add_command(upgrade)
+cli.add_command(verify)
+cli.add_command(cleanup)
diff --git a/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/cli/upgrade.py b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/cli/upgrade.py
new file mode 100644
index 000000000000..4bc2fbec059d
--- /dev/null
+++ b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/cli/upgrade.py
@@ -0,0 +1,71 @@
+"""
+Copyright 2021 The Magma Authors.
+
+This source code is licensed under the BSD-style license found in the
+LICENSE file in the root directory of this source tree.
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+import sys
+
+import click
+
+from .common import (
+ run_command,
+ run_playbook,
+ print_error_msg,
+ print_success_msg,
+ print_warning_msg
+)
+
+@click.group(invoke_without_command=True)
+@click.pass_context
+def upgrade(ctx):
+ """
+ Upgrade existing orc8r deployment
+ """
+ tf_cmds = [
+ ["terraform", "init", "--upgrade"],
+ ["terraform", "refresh"],
+ [ "terraform", "apply", "-auto-approve"]
+ ]
+
+ if ctx.invoked_subcommand is None:
+ if click.confirm('Do you want to run upgrade prechecks?'):
+ ctx.invoke(precheck)
+ else:
+ print_warning_msg(f"Skipping upgrade prechecks")
+
+ click.echo(
+ "Following commands will be run during upgrade\n%s" % (
+ "\n".join((map(" ".join, tf_cmds)))
+ ))
+ for cmd in tf_cmds:
+ if click.confirm('Do you want to continue with %s?' % " ".join(cmd)):
+ rc = run_command(cmd)
+ if rc != 0:
+ print_error_msg("Upgrade Failed!!!")
+ return
+
+@upgrade.command()
+@click.pass_context
+def precheck(ctx):
+ """
+ Precheck runs various checks to ensure successful upgrade
+ """
+ rc = run_playbook([
+ "ansible-playbook",
+ "-v",
+ "-e",
+ "@/root/config.yml",
+ "-t",
+ "upgrade_precheck",
+ "%s/main.yml" % ctx.obj["playbooks"]])
+ if rc != 0:
+ print_error_msg("Upgrade prechecks failed!!!")
+ sys.exit(1)
+ print_success_msg("Upgrade prechecks ran successfully")
\ No newline at end of file
diff --git a/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/cli/verify.py b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/cli/verify.py
new file mode 100644
index 000000000000..5f5296d4f779
--- /dev/null
+++ b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/cli/verify.py
@@ -0,0 +1,65 @@
+"""
+Copyright 2021 The Magma Authors.
+
+This source code is licensed under the BSD-style license found in the
+LICENSE file in the root directory of this source tree.
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+import os
+import sys
+import glob
+
+import click
+
+from .common import (
+ run_playbook,
+ print_error_msg,
+ print_success_msg)
+
+@click.group()
+@click.pass_context
+def verify(ctx):
+ """
+ Run post deployment checks on orc8r
+ """
+ pass
+
+@verify.command('sanity')
+@click.pass_context
+def verify_sanity(ctx):
+ # check if KUBECONFIG is set else find kubeconfig file and set the
+ # environment variable
+ constants = ctx.obj
+
+ # set kubeconfig
+ kubeconfig = os.environ.get('KUBECONFIG')
+ if not kubeconfig:
+ kubeconfigs = glob.glob(constants['project_dir'] + "/kubeconfig_*")
+ if len(kubeconfigs) != 1:
+ if len(kubeconfigs) == 0:
+ print_success_msg('No kubeconfig found!!!')
+ else:
+ print_error_msg("multiple kubeconfigs found %s!!!" % repr(kubeconfigs))
+ return
+ kubeconfig = kubeconfigs[0]
+
+ os.environ["KUBECONFIG"] = kubeconfig
+ os.environ["K8S_AUTH_KUBECONFIG"] = kubeconfig
+
+ rc = run_playbook([
+ "ansible-playbook",
+ "-v",
+ "-e",
+ "@/root/config.yml",
+ "-t",
+ "verify_sanity",
+ "%s/main.yml" % constants["playbooks"]])
+ if rc != 0:
+ print_error_msg("Post deployment verification checks failed!!!")
+ sys.exit(1)
+ print_success_msg("Post deployment verification ran successfully")
\ No newline at end of file
diff --git a/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/certs.yml b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/certs.yml
new file mode 100644
index 000000000000..3acb3c6c0735
--- /dev/null
+++ b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/certs.yml
@@ -0,0 +1,46 @@
+- hosts: localhost
+ tags: addcerts
+ tasks:
+ - name: Open configuration file
+ shell: "jq .orc8r_domain_name {{ config_dir }}/infra.tfvars.json"
+ ignore_errors: true
+ register: result
+
+ - name: Check for a valid orc8r domain name
+ assert:
+ that:
+ - result.rc == 0
+ - result.stdout != 'null'
+ fail_msg:
+ - "Failed reading valid orc8r domain name. "
+ - "Configure orc8r domain name 'orcl configure set -k orc8r_domain_name -v "
+
+ - name: Set orc8r domain name
+ set_fact:
+ orc8r_domain_name: "{{ result.stdout | from_json }}"
+
+ - name: Create certs directory
+ file:
+ name: "{{ secret_dir }}"
+ state: directory
+ mode: '0775'
+
+ - name: Generate self-signed certs
+ command: "{{ magma_root }}/orc8r/cloud/deploy/scripts/self_sign_certs.sh {{ orc8r_domain_name }}"
+ args:
+ chdir: "{{ secret_dir }}"
+ tags: self_signed
+
+ - name: Generate application certs
+ command: "{{ magma_root }}/orc8r/cloud/deploy/scripts/create_application_certs.sh {{ orc8r_domain_name }}"
+ args:
+ chdir: "{{ secret_dir }}"
+
+ - name: Generate admin operator certs as pfx bundle
+ openssl_pkcs12:
+ action: export
+ path: "{{ secret_dir }}/admin_operator.pfx"
+ friendly_name: orc8rpfx
+ privatekey_path: "{{ secret_dir }}/admin_operator.key.pem"
+ certificate_path: "{{ secret_dir }}/admin_operator.pem"
+ state: present
\ No newline at end of file
diff --git a/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/cleanup.yml b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/cleanup.yml
new file mode 100644
index 000000000000..e30019c98f4c
--- /dev/null
+++ b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/cleanup.yml
@@ -0,0 +1,10 @@
+- hosts: localhost
+ roles:
+ - role: deploy
+ - role: services/orc8r
+ - role: services
+ - role: platform
+ - role: infra/aws
+ vars_files:
+ - roles/deploy/vars/all.yml
+ - roles/services/vars/all.yml
\ No newline at end of file
diff --git a/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/main.yml b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/main.yml
new file mode 100644
index 000000000000..179c60371f9d
--- /dev/null
+++ b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/main.yml
@@ -0,0 +1,10 @@
+- hosts: localhost
+ roles:
+ - role: deploy
+ - role: infra/aws
+ - role: platform
+ - role: services
+ - role: services/orc8r
+ vars_files:
+ - roles/deploy/vars/all.yml
+ - roles/services/vars/all.yml
diff --git a/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/deploy/tasks/main.yml b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/deploy/tasks/main.yml
new file mode 100644
index 000000000000..8be463433194
--- /dev/null
+++ b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/deploy/tasks/main.yml
@@ -0,0 +1,5 @@
+- name: Secrets tasks
+ import_tasks: secrets.yml
+
+- name: Terraform tasks
+ import_tasks: tf.yml
diff --git a/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/deploy/tasks/secrets.yml b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/deploy/tasks/secrets.yml
new file mode 100644
index 000000000000..b4d880982be2
--- /dev/null
+++ b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/deploy/tasks/secrets.yml
@@ -0,0 +1,20 @@
+- name: Get information from secrets directory
+ stat:
+ path: "{{secret_dir}}/{{item}}"
+ register: st_info
+ with_items: "{{ ORC8R_CERTS + FLUENTD_CERTS + ADMIN_CERTS}}"
+ tags:
+ - install_precheck
+
+- name: Debug secrets
+ debug: msg="{{st_info}}"
+ tags:
+ - install_precheck
+
+- name: Check if secrets are missing
+ assert:
+ that: "{{item.stat.exists}}"
+ fail_msg: "Secret file {{item.item}} does not exist"
+ with_items: "{{st_info.results}}"
+ tags:
+ - install_precheck
\ No newline at end of file
diff --git a/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/deploy/tasks/tf.yml b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/deploy/tasks/tf.yml
new file mode 100644
index 000000000000..089224bbbbf3
--- /dev/null
+++ b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/deploy/tasks/tf.yml
@@ -0,0 +1,287 @@
+- name: Initialize terraform
+ ansible.builtin.command: terraform init
+ args:
+ chdir: "{{project_dir}}"
+ tags:
+ - install_precheck
+ - upgrade_precheck
+ - verify_sanity
+ - cleanup_dryrun
+ - cleanup
+
+- name: Get terraform state facts
+ ansible.builtin.command: "{% if cleanup_state is defined %} terraform show -json {{cleanup_state}} {% else %} terraform show -json {% endif %}"
+ register: result
+ args:
+ chdir: "{{project_dir}}"
+ tags:
+ - install_precheck
+ - upgrade_precheck
+ - verify_sanity
+ - cleanup_dryrun
+ - cleanup
+
+- name: Check if terraform state command errors out
+ assert:
+ that:
+ - result.rc == 0
+ msg: [
+ "Error attempting to run 'terraform show' command",
+ "Terraform state not found",
+ "Check if the deployment directory {{project_dir}} contains terraform files"
+ ]
+ tags:
+ - install_precheck
+ - upgrade_precheck
+ - verify_sanity
+ - cleanup_dryrun
+ - cleanup
+
+- name: Check if any resources are present in terraform state
+ assert:
+ that:
+ - "{{ (result.stdout | from_json) | json_query('values') != None }}"
+ msg: [
+ "No resources found in terraform state"
+ ]
+ tags:
+ - upgrade_precheck
+ - verify_sanity
+
+- name: Check if no resources are present in terraform state
+ assert:
+ that:
+ - "{{ (result.stdout | from_json) | json_query('values') == None }}"
+ fail_msg: "Prior terraform state present. Cleanup terraform.tfstate files or backend s3 state if necessary"
+ tags:
+ - install_precheck
+
+- name: Set terraform state fact
+ set_fact:
+ terraform_state: "{{result.stdout | from_json}}"
+ ignore_errors: true
+ tags:
+ - upgrade_precheck
+ - verify_sanity
+ - cleanup_dryrun
+ - cleanup
+
+- name: Set orc8r namespace
+ set_fact:
+ orc8r_namespace: "{{lookup('flattened', result.stdout | from_json | json_query(ORC8R_NAMESPACE_QUERY))}}"
+ when: orc8r_namespace is undefined
+ ignore_errors: true
+ tags:
+ - upgrade_precheck
+ - verify_sanity
+ - cleanup_dryrun
+ - cleanup
+
+- name: Debug orc8r namespace
+ debug:
+ msg: "orc8r_namespace : {{orc8r_namespace}}"
+ ignore_errors: true
+ tags:
+ - upgrade_precheck
+ - verify_sanity
+ - cleanup_dryrun
+ - cleanup
+
+- name: Set orc8r secrets
+ set_fact:
+ orc8r_secrets: "{{lookup('flattened', result.stdout | from_json | json_query(ORC8R_AWS_SECRETS_QUERY))}}"
+ ignore_errors: true
+ when: orc8r_secrets is undefined
+ tags:
+ - upgrade_precheck
+ - verify_sanity
+ - cleanup_dryrun
+ - cleanup
+
+- name: Debug orc8r secrets
+ debug:
+ msg: "orc8r_secrets : {{orc8r_secrets}}"
+ tags:
+ - upgrade_precheck
+ - verify_sanity
+ - cleanup_dryrun
+ - cleanup
+
+- name: Set orc8r ES domain
+ set_fact:
+ orc8r_es_domain: "{{lookup('flattened', result.stdout | from_json | json_query(ORC8R_ES_DOMAIN_QUERY))}}"
+ ignore_errors: true
+ when: orc8r_es_domain is undefined
+ tags:
+ - upgrade_precheck
+ - verify_sanity
+ - cleanup_dryrun
+ - cleanup
+
+- name: Debug orc8r es domain
+ debug:
+ msg: "orc8r_es_domain : {{orc8r_es_domain}}"
+ tags:
+ - upgrade_precheck
+ - verify_sanity
+ - cleanup_dryrun
+ - cleanup
+
+- name: Set orc8r cluster name
+ set_fact:
+ orc8r_cluster_name: "{{lookup('flattened', result.stdout | from_json | json_query(ORC8R_CLUSTER_NAME_QUERY))}}"
+ when: orc8r_cluster_name is undefined
+ ignore_errors: true
+ tags:
+ - upgrade_precheck
+ - verify_sanity
+ - cleanup_dryrun
+ - cleanup
+
+- name: Debug orc8r cluster name
+ debug:
+ msg: "orc8r_cluster_name : {{orc8r_cluster_name}}"
+ tags:
+ - upgrade_precheck
+ - verify_sanity
+ - cleanup_dryrun
+ - cleanup
+
+- name: Set orc8r db instance id
+ set_fact:
+ orc8r_db_id: "{{lookup('flattened', result.stdout | from_json | json_query(ORC8R_DB_ID_QUERY))}}"
+ when: orc8r_db_id is undefined
+ ignore_errors: true
+ tags:
+ - upgrade_precheck
+ - verify_sanity
+ - cleanup_dryrun
+ - cleanup
+
+- name: Debug orc8r db instance
+ debug:
+ msg: "orc8r_db_id : {{orc8r_db_id}}"
+ tags:
+ - upgrade_precheck
+ - verify_sanity
+ - cleanup_dryrun
+ - cleanup
+
+- name: Set orc8r db subnet
+ set_fact:
+ orc8r_db_subnet: "{{lookup('flattened', result.stdout | from_json | json_query(ORC8R_DB_SUBNET_QUERY))}}"
+ ignore_errors: true
+ tags:
+ - upgrade_precheck
+ - verify_sanity
+ - cleanup_dryrun
+ - cleanup
+
+- name: Debug orc8r db subnet
+ debug:
+ msg: "orc8r_db_subnet : {{orc8r_db_subnet}}"
+ tags:
+ - upgrade_precheck
+ - verify_sanity
+ - cleanup_dryrun
+ - cleanup
+
+- name: Set EFS mount targets
+ set_fact:
+ efs_mount_targets: "{{lookup('flattened', result.stdout | from_json | json_query(EFS_MOUNT_TARGET_ID_QUERY), wantlist=True)}}"
+ ignore_errors: true
+ when: efs_mount_targets is undefined
+ tags:
+ - upgrade_precheck
+ - verify_sanity
+ - cleanup_dryrun
+ - cleanup
+
+- name: Debug EFS mount targets
+ debug:
+ msg: "efs_mount_targets : {{efs_mount_targets}}"
+ tags:
+ - upgrade_precheck
+ - verify_sanity
+ - cleanup_dryrun
+ - cleanup
+
+- name: Set EFS FS targets
+ set_fact:
+ efs_fs_targets: "{{lookup('flattened', result.stdout | from_json | json_query(EFS_FILE_SYSTEM_ID_QUERY), wantlist=True)}}"
+ ignore_errors: true
+ when: efs_fs_targets is undefined
+ tags:
+ - upgrade_precheck
+ - verify_sanity
+ - cleanup_dryrun
+ - cleanup
+
+- name: Debug EFS FS targets
+ debug:
+ msg: "efs_fs_targets : {{efs_fs_targets}}"
+ tags:
+ - upgrade_precheck
+ - verify_sanity
+ - cleanup_dryrun
+ - cleanup
+
+- name: Set vpc
+ set_fact:
+ vpc: "{{lookup('flattened', result.stdout | from_json | json_query(VPC_QUERY))}}"
+ ignore_errors: true
+ when: vpc is undefined
+ tags:
+ - upgrade_precheck
+ - verify_sanity
+ - cleanup_dryrun
+ - cleanup
+
+- name: Debug vpc
+ debug:
+ msg: "vpc : {{vpc}}"
+ tags:
+ - upgrade_precheck
+ - verify_sanity
+ - cleanup_dryrun
+ - cleanup
+
+- name: Set hosted zone
+ set_fact:
+ hosted_zone: "{{lookup('flattened', result.stdout | from_json | json_query(HOSTED_ZONE_QUERY))}}"
+ ignore_errors: true
+ when: hosted_zone is undefined
+ tags:
+ - upgrade_precheck
+ - verify_sanity
+ - cleanup_dryrun
+ - cleanup
+
+- name: Debug hosted zone
+ debug:
+ msg: "hosted_zone : {{hosted_zone}}"
+ tags:
+ - upgrade_precheck
+ - verify_sanity
+ - cleanup_dryrun
+ - cleanup
+
+- name: Set region name
+ set_fact:
+ region_name: "{{lookup('flattened', result.stdout | from_json | json_query(REGION_QUERY) | first)}}"
+ ignore_errors: true
+ when: region_name is undefined
+ tags:
+ - upgrade_precheck
+ - verify_sanity
+ - cleanup_dryrun
+ - cleanup
+
+- name: Debug region name
+ debug:
+ msg: "region_name : {{region_name}}"
+ tags:
+ - upgrade_precheck
+ - verify_sanity
+ - cleanup_dryrun
+ - cleanup
\ No newline at end of file
diff --git a/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/deploy/vars/all.yml b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/deploy/vars/all.yml
new file mode 100644
index 000000000000..0d23222e6edd
--- /dev/null
+++ b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/deploy/vars/all.yml
@@ -0,0 +1,29 @@
+ORC8R_NAMESPACE_QUERY: "values.root_module.child_modules[*].resources[?address=='module.orc8r-app.kubernetes_namespace.orc8r'].values.metadata[*].name"
+ORC8R_AWS_SECRETS_QUERY: "values.root_module.child_modules[*].resources[?address=='module.orc8r.aws_secretsmanager_secret.orc8r_secrets'].values.name"
+ORC8R_ES_DOMAIN_QUERY: "values.root_module.child_modules[*].resources[?type=='aws_elasticsearch_domain'].values.domain_name"
+ORC8R_CLUSTER_NAME_QUERY: "values.root_module.child_modules[*].resources[?address=='module.orc8r-app.data.aws_eks_cluster.cluster'].values.name"
+ORC8R_DB_ID_QUERY: "values.root_module.child_modules[*].resources[?address=='module.orc8r.aws_db_instance.default'].values.id"
+ORC8R_DB_SUBNET_QUERY: "values.root_module.child_modules[*].resources[?address=='module.orc8r.aws_db_instance.default'].values.db_subnet_group_name"
+NMS_DB_ID_QUERY: "values.root_module.child_modules[*].resources[?address=='module.orc8r.aws_db_instance.nms'].values.id"
+EFS_MOUNT_TARGET_ID_QUERY: "values.root_module.child_modules[*].resources[?type=='aws_efs_mount_target'].values.id"
+EFS_FILE_SYSTEM_ID_QUERY: "values.root_module.child_modules[*].resources[?type=='aws_efs_mount_target'].values.file_system_id"
+HOSTED_ZONE_QUERY: "values.root_module.child_modules[*].resources[?address=='module.orc8r.aws_route53_zone.orc8r'].values"
+VPC_QUERY: "values.root_module.child_modules[*].child_modules[*].resources[?type=='aws_vpc'].values"
+REGION_QUERY: "values.root_module.child_modules[*].resources[?type=='aws_availability_zones'].values.id"
+
+ORC8R_CERTS:
+ - 'rootCA.pem'
+ - 'rootCA.key'
+ - 'controller.key'
+ - 'controller.crt'
+ - 'certifier.key'
+ - 'certifier.pem'
+ - 'bootstrapper.key'
+
+FLUENTD_CERTS:
+ - 'fluentd.key'
+ - 'fluentd.pem'
+
+ADMIN_CERTS:
+ - 'admin_operator.pem'
+ - 'admin_operator.key.pem'
\ No newline at end of file
diff --git a/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/infra/aws/tasks/az.yml b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/infra/aws/tasks/az.yml
new file mode 100644
index 000000000000..f16364ee7bfd
--- /dev/null
+++ b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/infra/aws/tasks/az.yml
@@ -0,0 +1,15 @@
+- name: Check if we have atleast 3 availability zones in our deployment
+ amazon.aws.aws_az_info:
+ register: aws_az_info
+ failed_when: aws_az_info.availability_zones | length < 3
+ tags:
+ - install_precheck
+ - upgrade_precheck
+
+- name: Debug availability zones present in our region
+ amazon.aws.aws_az_info:
+ register: aws_az_info
+ failed_when: aws_az_info.availability_zones | length < 3
+ tags:
+ - install_precheck
+ - upgrade_precheck
\ No newline at end of file
diff --git a/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/infra/aws/tasks/efs.yml b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/infra/aws/tasks/efs.yml
new file mode 100644
index 000000000000..d5122e7cc7f6
--- /dev/null
+++ b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/infra/aws/tasks/efs.yml
@@ -0,0 +1,19 @@
+- name: Delete efs mount targets
+ command: aws efs delete-mount-target --mount-target-id "{{ item }}"
+ with_items: "{{ efs_mount_targets }}"
+ ignore_errors: true
+ tags: cleanup
+
+- name: Sleep for a while before deleting filesystem
+ pause:
+ minutes: 2
+ when: efs_mount_targets
+ tags: cleanup
+
+- name: Delete efs volumes
+ command: aws efs delete-file-system --file-system-id "{{ item }}"
+ with_items: "{{ efs_fs_targets }}"
+ ignore_errors: true
+ when: efs_fs_targets
+ tags: cleanup
+
diff --git a/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/infra/aws/tasks/eks.yml b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/infra/aws/tasks/eks.yml
new file mode 100644
index 000000000000..5b5eaa6914c0
--- /dev/null
+++ b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/infra/aws/tasks/eks.yml
@@ -0,0 +1,56 @@
+- name: Get EKS cluster information
+ ansible.builtin.shell: aws eks describe-cluster --name {{ infra_configs.cluster_name | quote }} || /bin/true
+ register: result
+ tags: upgrade_precheck
+
+- name: Check if deployed EKS cluster version is greater than version specified in values
+ assert:
+ that: "{{ infra_configs.cluster_version is version((result.stdout | from_json).cluster.version, '>=') }}"
+ msg:
+ - "deployed version higher than to be configured version"
+ - "Configure the cluster_version to be >= {{(result.stdout | from_json).cluster.version}}"
+ - "For e.g: orcl configure set -c infra -k cluster_version -v {{(result.stdout | from_json).cluster.version}}"
+ when: '"ResourceNotFoundException" not in result.stderr'
+ tags: upgrade_precheck
+
+- name: Cleanup eks cluster
+ aws_eks_cluster:
+ name: "{{ orc8r_cluster_name }}"
+ wait: yes
+ state: absent
+ ignore_errors: true
+ tags:
+ - cleanup
+
+- name: Get autoscaling groups
+ ec2_asg_info:
+ tags:
+ k8s.io/cluster-autoscaler/orc8r: "{{ orc8r_cluster_name }}"
+ register: asg_cluster_info
+ ignore_errors: true
+ tags:
+ - cleanup
+ - cleanup_dryrun
+
+- name: Debug autoscaling groups
+ debug:
+ msg: "{{ asg_cluster_info }}"
+ ignore_errors: true
+ tags:
+ - cleanup
+ - cleanup_dryrun
+
+- name: Set autoscaling group fact
+ set_fact:
+ asg_name: "{{ asg_cluster_info.results[0].auto_scaling_group_name }}"
+ ignore_errors: true
+ when: asg_cluster_info.results | length
+ tags:
+ - cleanup
+
+- name: Delete autoscaling group
+ command: aws autoscaling delete-auto-scaling-group --auto-scaling-group-name "{{ asg_name }}" --force-delete
+ ignore_errors: true
+ when: asg_cluster_info.results | length
+ tags:
+ - cleanup
diff --git a/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/infra/aws/tasks/elb.yml b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/infra/aws/tasks/elb.yml
new file mode 100644
index 000000000000..3c19a19e6c5a
--- /dev/null
+++ b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/infra/aws/tasks/elb.yml
@@ -0,0 +1,33 @@
+- name: Collect all elb information
+ ec2_elb_info:
+ region: "{{ region_name }}"
+ register: elb_info
+ ignore_errors: true
+ when: region_name
+ tags:
+ - cleanup_dryrun
+ - cleanup
+
+- name: Debug elb information
+ debug:
+ msg: "{{item}}"
+ ignore_errors: true
+ when: region_name and vpc and item.vpc_id == vpc.id
+ with_items:
+ - "{{ elb_info.elbs }}"
+ tags:
+ - cleanup_dryrun
+ - cleanup
+
+- name: Delete all elbs
+ ec2_elb_lb:
+ state: absent
+ name: "{{ item.name }}"
+ region: "{{ region_name }}"
+ wait: yes
+ when: region_name and vpc and item.vpc_id == vpc.id
+ ignore_errors: true
+ with_items:
+ - "{{ elb_info.elbs }}"
+ tags:
+ - cleanup
diff --git a/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/infra/aws/tasks/main.yml b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/infra/aws/tasks/main.yml
new file mode 100644
index 000000000000..c901d4108220
--- /dev/null
+++ b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/infra/aws/tasks/main.yml
@@ -0,0 +1,42 @@
+- name: Check if required infra variables are set
+ ansible.builtin.command: "orcl configure check -c infra"
+ register: result
+ failed_when: result.rc != 0
+ tags:
+ - install_precheck
+ - upgrade_precheck
+
+- name: Open configuration file
+ shell: "cat {{config_dir}}/infra.tfvars.json"
+ register: result
+ tags:
+ - install_precheck
+ - upgrade_precheck
+
+- name: Set Infra Configs
+ set_fact:
+ infra_configs: "{{ result.stdout | from_json }}"
+ tags:
+ - install_precheck
+ - upgrade_precheck
+
+- name: Availability zone tasks
+ import_tasks: az.yml
+
+- name: Secret manager tasks
+ import_tasks: secrets.yml
+
+- name: EKS tasks
+ import_tasks: eks.yml
+
+- name: ELB tasks
+ import_tasks: elb.yml
+
+- name: EFS tasks
+ import_tasks: efs.yml
+
+- name: VPC tasks
+ import_tasks: vpc.yml
+
+- name: Route53 tasks
+ import_tasks: route53.yml
\ No newline at end of file
diff --git a/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/infra/aws/tasks/route53.yml b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/infra/aws/tasks/route53.yml
new file mode 100644
index 000000000000..1e8d4319f288
--- /dev/null
+++ b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/infra/aws/tasks/route53.yml
@@ -0,0 +1,109 @@
+- name: Get all txt resource record sets
+ community.aws.route53:
+ command: get
+ zone: "{{hosted_zone.name}}"
+ record: "{{item[0]}}.{{hosted_zone.name}}"
+ type: "TXT"
+ register: current_dns_records
+ ignore_errors: true
+ with_items: ['bootstrapper-controller', 'controller', '*.nms', 'fluentd', 'api']
+ tags:
+ - cleanup
+ - cleanup_dryrun
+
+- name: Debug all txt resource record sets
+ debug: msg="{{current_dns_records}}"
+ tags:
+ - cleanup_dryrun
+ - cleanup
+
+# HACK - deleting a record fails due to some oddities in value. Hence
+# setting to a empty value and deleting it.
+- name: Change all txt resource record sets
+ community.aws.route53:
+ state: present
+ overwrite: true
+ zone: "{{ hosted_zone.name }}"
+ record: "{{item.item}}.{{hosted_zone.name}}"
+ ttl: "{{ item.set.ttl | default('300') }}"
+ type: "TXT"
+ value: "{{ value | to_json }}"
+ wait: yes
+ loop: "{{ current_dns_records.results }}"
+ ignore_errors: true
+ vars:
+ value: ""
+ tags: cleanup
+
+- name: Delete all txt resource record sets
+ community.aws.route53:
+ state: absent
+ overwrite: true
+ zone: "{{ hosted_zone.name }}"
+ record: "{{item.item}}.{{hosted_zone.name}}"
+ ttl: "{{ item.set.ttl | default('300') }}"
+ type: "TXT"
+ value: "{{ value | to_json }}"
+ wait: yes
+ vars:
+ value: ""
+ loop: "{{ current_dns_records.results }}"
+ ignore_errors: true
+ tags: cleanup
+
+- name: Get all alias resource record sets
+ community.aws.route53:
+ command: get
+ zone: "{{hosted_zone.name}}"
+ record: "{{item[0]}}.{{hosted_zone.name}}"
+ type: "A"
+ register: current_dns_records
+ ignore_errors: true
+ with_items: ['bootstrapper-controller', 'controller', '*.nms', 'fluentd', 'api']
+ tags:
+ - cleanup
+ - cleanup_dryrun
+
+- name: Debug all alias resource record sets
+ debug: msg="{{current_dns_records}}"
+ tags:
+ - cleanup_dryrun
+ - cleanup
+
+# HACK - deleting a record fails due to some oddities in value. Hence
+# setting to a empty value and deleting it.
+- name: Change all alias resource record sets
+ community.aws.route53:
+ state: present
+ overwrite: true
+ zone: "{{ hosted_zone.name }}"
+ record: "{{item.item}}.{{hosted_zone.name}}"
+ ttl: "{{ item.set.ttl | default('300') }}"
+ type: "A"
+ value: 0.0.0.0
+ wait: yes
+ loop: "{{ current_dns_records.results }}"
+ ignore_errors: true
+ tags: cleanup
+
+- name: Delete all alias resource record sets
+ community.aws.route53:
+ state: absent
+ overwrite: true
+ zone: "{{ hosted_zone.name }}"
+ record: "{{item.item}}.{{hosted_zone.name}}"
+ ttl: "{{ item.set.ttl | default('300') }}"
+ type: "A"
+ value: 0.0.0.0
+ wait: yes
+ loop: "{{ current_dns_records.results }}"
+ ignore_errors: true
+ tags: cleanup
+
+- name: Delete hosted zones for orc8r domain
+ community.aws.route53_zone:
+ zone: "{{hosted_zone.name}}"
+ hosted_zone_id: "{{hosted_zone.zone_id}}"
+ state: absent
+ ignore_errors: true
+ tags: cleanup
\ No newline at end of file
diff --git a/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/infra/aws/tasks/secrets.yml b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/infra/aws/tasks/secrets.yml
new file mode 100644
index 000000000000..622ccfeb1fd0
--- /dev/null
+++ b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/infra/aws/tasks/secrets.yml
@@ -0,0 +1,19 @@
+- name: Query secretsmanager
+ ansible.builtin.shell: aws secretsmanager list-secret-version-ids --secret-id {{ infra_configs.secretsmanager_orc8r_secret | quote }} || /bin/true
+ register: result
+ tags: install_precheck
+
+- name: Verify if secrets already present
+ assert:
+ that: '"ResourceNotFoundException" in result.stderr'
+ fail_msg:
+ - "secret {{ infra_configs.secretsmanager_orc8r_secret}} already present"
+ - "Remove secrets 'aws secretsmanager delete-secret --force-delete --secret-id {{ infra_configs.secretsmanager_orc8r_secret | quote }}'"
+ tags: install_precheck
+
+- name: Delete secretsmanager forcefully
+ command: aws secretsmanager delete-secret --force-delete --secret-id "{{ orc8r_secrets }}"
+ when: orc8r_secrets
+ ignore_errors: true
+ tags:
+ - cleanup
diff --git a/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/infra/aws/tasks/vpc.yml b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/infra/aws/tasks/vpc.yml
new file mode 100644
index 000000000000..87b0b3202847
--- /dev/null
+++ b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/infra/aws/tasks/vpc.yml
@@ -0,0 +1,157 @@
+- name: Get all NAT gateways for this VPC
+ ec2_vpc_nat_gateway_info:
+ filters:
+ vpc-id: "{{ vpc.id }}"
+ register: natgw_info
+ when: vpc
+ ignore_errors: true
+ tags:
+ - cleanup
+ - cleanup_dryrun
+
+- name: Debug NAT gateways for this vpc
+ when: vpc
+ debug: msg="{{natgw_info}}"
+ ignore_errors: true
+ tags:
+ - cleanup
+ - cleanup_dryrun
+
+- name: Delete all nat gateways
+ ec2_vpc_nat_gateway:
+ state: absent
+ nat_gateway_id: "{{ item.nat_gateway_id }}"
+ release_eip: true
+ wait: yes
+ when: vpc
+ with_items: "{{ natgw_info.result }}"
+ ignore_errors: true
+ tags: cleanup
+
+- name: Get all internet gateways attached to this VPC
+ ec2_vpc_igw_info:
+ filters:
+ "tag:Name": "{{ vpc.tags['Name'] }}"
+ "attachment.state": "available"
+ register: igw_info
+ when: vpc
+ ignore_errors: true
+ tags:
+ - cleanup
+ - cleanup_dryrun
+
+- name: Debug internet gateways for this vpc
+ debug: msg="{{igw_info}}"
+ when: vpc
+ ignore_errors: true
+ tags:
+ - cleanup
+ - cleanup_dryrun
+
+- name: Detach internet gateway from VPC
+ command: aws ec2 detach-internet-gateway --internet-gateway-id "{{ item.internet_gateway_id }}" --vpc-id "{{ vpc.id }}"
+ ignore_errors: true
+ when: vpc
+ with_items: "{{igw_info.internet_gateways}}"
+ tags: cleanup
+
+- name: Delete internet gateway
+ command: aws ec2 delete-internet-gateway --internet-gateway-id "{{ item.internet_gateway_id }}"
+ ignore_errors: true
+ when: vpc
+ with_items: "{{igw_info.internet_gateways}}"
+ tags: cleanup
+
+- name: Find subnets of this vpc
+ ec2_vpc_subnet_info:
+ filters:
+ vpc-id: "{{ vpc.id }}"
+ when: vpc
+ register: subnet_info
+ ignore_errors: true
+ tags:
+ - cleanup
+ - cleanup_dryrun
+
+- name: Debug all subnets
+ debug:
+ msg: "{{subnet_info}}"
+ when: vpc
+ tags:
+ - cleanup
+ - cleanup_dryrun
+
+- name: Delete all subnets
+ ec2_vpc_subnet:
+ state: absent
+ vpc_id: "{{ item.vpc_id }}"
+ cidr: "{{ item.cidr_block }}"
+ when: item.default_for_az == false
+ with_items: "{{ subnet_info.subnets }}"
+ ignore_errors: true
+ tags: cleanup
+
+- name: Get all route tables for this subnet
+ ec2_vpc_route_table_info:
+ filters:
+ vpc_id: "{{ vpc.id }}"
+ region: "{{ region_name }}"
+ register: rt_info
+ when: vpc
+ ignore_errors: true
+ tags:
+ - cleanup
+ - cleanup_dryrun
+
+- name: Debug routing info
+ debug:
+ msg: "{{ rt_info }}"
+ ignore_errors: true
+ tags:
+ - cleanup
+ - cleanup_dryrun
+
+- name: Delete all route tables for this vpc
+ command: aws ec2 delete-route-table --route-table-id "{{ item.id }}"
+ when: item.associations[0] is not defined
+ with_items:
+ - "{{ rt_info.route_tables }}"
+ ignore_errors: true
+ tags: cleanup
+
+- name: Get all security groups for this vpc
+ ec2_group_info:
+ filters:
+ vpc_id: "{{ vpc.id }}"
+ register: sec_info
+ when: vpc
+ ignore_errors: true
+ tags:
+ - cleanup
+ - cleanup_dryrun
+
+- name: Debug security groups
+ debug:
+ msg: "{{ sec_info }}"
+ tags:
+ - cleanup
+ - cleanup_dryrun
+
+- name: Delete all security groups in this VPC
+ ec2_group:
+ group_id: "{{ item.group_id }}"
+ state: absent
+ when: vpc and item.group_name != "default"
+ with_items:
+ - "{{ sec_info.security_groups }}"
+ ignore_errors: true
+ tags: cleanup
+
+- name: Delete vpc
+ ec2_vpc_net:
+ state: absent
+ name: "{{ vpc.tags['Name'] }}"
+ cidr_block: "{{ vpc.cidr_block }}"
+ ignore_errors: true
+ when: vpc
+ tags: cleanup
\ No newline at end of file
diff --git a/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/platform/tasks/cloudwatch.yml b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/platform/tasks/cloudwatch.yml
new file mode 100644
index 000000000000..e88866af55d2
--- /dev/null
+++ b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/platform/tasks/cloudwatch.yml
@@ -0,0 +1,33 @@
+---
+- name: Check if required infra variables are set
+ ansible.builtin.command: "orcl configure check -c infra"
+ register: result
+ failed_when: result.rc != 0
+ tags: install_precheck
+
+- name: Open configuration file
+ shell: "cat {{ config_dir }}/infra.tfvars.json"
+ register: result
+ tags: install_precheck
+
+- name: Set Infra Configs
+ set_fact:
+ infra_configs: "{{ result.stdout | from_json }}"
+ tags: install_precheck
+
+- name: Get all cloudwatch log groups
+ ansible.builtin.shell: aws logs describe-log-groups --output json
+ register: result
+ tags: install_precheck
+
+- name: Check if orc8r cloudwatch log group exists
+ fail:
+ msg: "Cloudwatch Log group still exists"
+ when: '"eks/{{infra_configs.cluster_name}}/cluster" in item.logGroupName'
+ with_items: "{{ (result.stdout|from_json).logGroups }}"
+ tags: install_precheck
+
+- name: Delete orchestrator cloudwatch group
+ command: aws logs delete-log-group --log-group-name "/aws/eks/{{ orc8r_cluster_name }}/cluster"
+ ignore_errors: true
+ tags: cleanup
\ No newline at end of file
diff --git a/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/platform/tasks/elastic.yml b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/platform/tasks/elastic.yml
new file mode 100644
index 000000000000..693a66403a23
--- /dev/null
+++ b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/platform/tasks/elastic.yml
@@ -0,0 +1,30 @@
+- name: Get AWS IAM roles information
+ ansible.builtin.shell: aws iam list-roles || /bin/true
+ register: result
+ when: platform_configs.deploy_elasticsearch
+ tags:
+ - install_precheck
+ - upgrade_precheck
+
+- name: Check if AWSServiceRoleForAmazonElasticsearchService is present already
+ assert:
+ that:
+ - "{{ platform_configs.deploy_elasticsearch_service_linked_role not in (true, 'true') or item.RoleName != 'AWSServiceRoleForAmazonElasticsearchService' }}"
+ msg:
+ - "IAM role AWSServiceRoleForAmazonElasticsearchService already exists"
+ - "Configure deploy_elasticsearch_service_linked_role to be false"
+ - "For e.g: orcl configure set -c platform -k deploy_elasticsearch_service_linked_role -v false"
+ when: platform_configs.deploy_elasticsearch
+ with_items: "{{(result.stdout | from_json).Roles}}"
+ tags:
+ - install_precheck
+ - upgrade_precheck
+
+- name: Cleanup elastic search instance
+ command: aws es delete-elasticsearch-domain --domain-name "{{ orc8r_es_domain }}"
+ ignore_errors: true
+ when: orc8r_es_domain
+ tags:
+ - cleanup
+
+
diff --git a/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/platform/tasks/main.yml b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/platform/tasks/main.yml
new file mode 100644
index 000000000000..81e55380925d
--- /dev/null
+++ b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/platform/tasks/main.yml
@@ -0,0 +1,30 @@
+- name: Check if required platform variables are set
+ ansible.builtin.command: "orcl configure check -c platform"
+ register: result
+ failed_when: result.rc != 0
+ tags:
+ - install_precheck
+ - upgrade_precheck
+
+- name: Open configuration file
+ shell: "cat {{config_dir}}/platform.tfvars.json"
+ register: result
+ tags:
+ - install_precheck
+ - upgrade_precheck
+
+- name: Set platform Configs
+ set_fact:
+ platform_configs: "{{ result.stdout | from_json }}"
+ tags:
+ - install_precheck
+ - upgrade_precheck
+
+- name: Cloudwatch tasks
+ import_tasks: cloudwatch.yml
+
+- name: RDS tasks
+ import_tasks: rds.yml
+
+- name: Elastic tasks
+ import_tasks: elastic.yml
diff --git a/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/platform/tasks/rds.yml b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/platform/tasks/rds.yml
new file mode 100644
index 000000000000..3222022c2f6c
--- /dev/null
+++ b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/platform/tasks/rds.yml
@@ -0,0 +1,39 @@
+- name: Get RDS information
+ ansible.builtin.shell: aws rds describe-db-instances || /bin/true
+ register: result
+ tags: upgrade_precheck
+
+- name: Check if deployed RDS db instance version is greater than version specified in values
+ assert:
+ that: "{{ platform_configs.orc8r_db_engine_version is version(item.EngineVersion, '>=') }}"
+ msg:
+ - "deployed version higher than to be configured version"
+ - "Configure the db engine version to be >= {{item.EngineVersion}}"
+ - "For e.g: orcl configure set -c infra -k orc8r_db_engine_version -v {{item.EngineVersion}}"
+ when: item.DBInstanceIdentifier == platform_configs.orc8r_db_identifier
+ with_items: "{{(result.stdout | from_json).DBInstances}}"
+ tags: upgrade_precheck
+
+- name: Delete rds instances
+ command: aws rds delete-db-instance --db-instance-identifier "{{ item }}" --skip-final-snapshot
+ when: item
+ with_items:
+ - "{{ orc8r_db_id }}"
+ # - "{{ nms_db_id }}"
+ ignore_errors: true
+ tags: cleanup
+
+- name: Wait for database deletion before deleting subnet group
+ command: aws rds wait db-instance-deleted --db-instance-identifier "{{ item }}"
+ when: item
+ with_items:
+ - "{{ orc8r_db_id }}"
+ # - "{{ nms_db_id }}"
+ ignore_errors: true
+ tags: cleanup
+
+- name: Delete rds subnet group
+ command: aws rds delete-db-subnet-group --db-subnet-group-name "{{ orc8r_db_subnet }}"
+ ignore_errors: true
+ when: orc8r_db_subnet
+ tags: cleanup
\ No newline at end of file
diff --git a/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/services/orc8r/tasks/main.yml b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/services/orc8r/tasks/main.yml
new file mode 100644
index 000000000000..9cb1f5aa1335
--- /dev/null
+++ b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/services/orc8r/tasks/main.yml
@@ -0,0 +1,82 @@
+- name: Gather kubernetes pod status for orc8r namespace
+ ansible.builtin.shell: kubectl get pods -o json -n "{{orc8r_namespace}}"
+ register: kubectl_output
+ tags: verify_sanity
+
+- name: Check if any pods are unhealthy
+ assert:
+ that:
+ - "{{pod_status | length == 0}}"
+ fail_msg: "found pods {{pod_status}} not in running state"
+ vars:
+ status_query: "items[?status.phase != 'Running'].metadata.name"
+ pod_status: "{{kubectl_output.stdout | from_json | json_query(status_query)}}"
+ tags: verify_sanity
+
+- name: Get the logs for pods in unhealthy state
+ ansible.builtin.shell: kubectl -n "{{orc8r_namespace}}" logs --tail=50 "{{item}}"
+ register: result
+ vars:
+ status_query: "items[?status.phase != 'Running'].metadata.name"
+ pod_status: "{{kubectl_output.stdout | from_json | json_query(status_query)}}"
+ with_items: "{{pod_status}}"
+ tags: verify_sanity
+
+- name: Dump the logs for pods in unhealthy state
+ debug: msg="Logs for {{item.item}} \n {{item.stdout_lines}}"
+ with_items: "{{result.results}}"
+ tags: verify_sanity
+
+- name: Get orchestrator pod name
+ ansible.builtin.shell: kubectl get pod -n "{{orc8r_namespace}}" -l app.kubernetes.io/component=orchestrator -o json
+ register: result
+ tags: verify_sanity
+
+- name: Set orchestrator pod name
+ set_fact:
+ orc_pod: "{{result.stdout | from_json | json_query(pod_query)}}"
+ vars:
+ pod_query: "items[0].metadata.name"
+
+ tags:
+ - 'verify_sanity'
+
+- name: Get NMS pod name
+ ansible.builtin.shell: kubectl get pod -n "{{orc8r_namespace}}" -l app.kubernetes.io/component=magmalte -o json
+ register: result
+ tags: verify_sanity
+
+- name: Set orchestrator pod name
+ set_fact:
+ nms_pod: "{{result.stdout | from_json | json_query(pod_query)}}"
+ api_host: "{{lookup('flattened', result.stdout | from_json | json_query(api_host_query))}}"
+ api_cert: "{{lookup('flattened', result.stdout | from_json | json_query(api_cert_query))}}"
+ api_key: "{{lookup('flattened', result.stdout | from_json | json_query(api_key_query))}}"
+ vars:
+ pod_query: "items[0].metadata.name"
+ api_host_query: "items[0].spec.containers[*].env[?name == 'API_HOST'].value"
+ api_cert_query: "items[0].spec.containers[*].env[?name == 'API_CERT_FILENAME'].value"
+ api_key_query: "items[0].spec.containers[*].env[?name == 'API_PRIVATE_KEY_FILENAME'].value"
+ tags:
+ - 'verify_sanity'
+
+- name: Add admin cert to orchestrator pod
+ ansible.builtin.shell: kubectl -n "{{orc8r_namespace}}" exec "{{orc_pod}}" -- envdir /var/opt/magma/envdir /var/opt/magma/bin/accessc add-existing -admin -cert /var/opt/magma/certs/admin_operator.pem admin_operator
+ register: result
+ failed_when: result.rc != 0 and 'AlreadyExists' not in result.stderr
+ tags: verify_sanity
+
+
+- name: List admin certs in orchestrator pod
+ ansible.builtin.shell: kubectl -n "{{orc8r_namespace}}" exec "{{orc_pod}}" -- envdir /var/opt/magma/envdir /var/opt/magma/bin/accessc list-certs
+ register: result
+ failed_when: result.rc != 0 or 'admin_operator' not in result.stdout
+ tags: verify_sanity
+
+- name: Get all configured networks from NMS pod
+ ansible.builtin.shell: kubectl -n "{{orc8r_namespace}}" exec "{{nms_pod}}" -- curl --cert "{{api_cert}}" --key "{{api_key}}" -k -X GET https://"{{api_host}}"/"{{item}}"
+ register: result
+ tags: verify_sanity
+ with_items:
+ - magma/v1/networks
+ - magma/v1/lte
\ No newline at end of file
diff --git a/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/services/tasks/docker.yml b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/services/tasks/docker.yml
new file mode 100644
index 000000000000..9df271e97135
--- /dev/null
+++ b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/services/tasks/docker.yml
@@ -0,0 +1,17 @@
+- name: Verify image credentials
+ docker_login:
+ registry: "{{service_configs.docker_registry}}"
+ username: "{{service_configs.docker_user}}"
+ password: "{{service_configs.docker_pass}}"
+ reauthorize: yes
+ tags: install_precheck
+
+- name: Attempting to pull the images
+ docker_image:
+ tag: "{{service_configs.orc8r_tag}}"
+ name: "{{service_configs.docker_registry}}/{{item}}"
+ force_source: true
+ source: pull
+ tags: install_precheck
+ with_items:
+ - "{{vars.ORC8R_IMAGES}}"
diff --git a/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/services/tasks/helm.yml b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/services/tasks/helm.yml
new file mode 100644
index 000000000000..85258c4f39a8
--- /dev/null
+++ b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/services/tasks/helm.yml
@@ -0,0 +1,90 @@
+- name: Set helm repo credentials
+ set_fact:
+ helm_cred_options: ""
+ when: service_configs.helm_user
+ tags:
+ - install_precheck
+ - upgrade_precheck
+
+- name: Verify the Helm repo
+ ansible.builtin.shell: "helm repo add test {{service_configs.helm_repo}} {% if service_configs.helm_user != '' %} --username {{service_configs.helm_user}} --password {{service_configs.helm_pass}} {% endif %}"
+ tags:
+ - install_precheck
+ - upgrade_precheck
+
+- name: Get all charts present in the Helm repo
+ ansible.builtin.shell: helm search repo test -o json
+ register: helm_chart_info
+ tags:
+ - install_precheck
+ - upgrade_precheck
+
+- name: Get chart name and version from Helm list
+ set_fact:
+ chart_version_map: "{{ chart_version_map | default({}) | combine({item.name.split('/')[1]: item.version}) }}"
+ with_items: "{{ helm_chart_info.stdout }}"
+ tags:
+ - install_precheck
+ - upgrade_precheck
+
+- name: Set chart version map
+ set_fact:
+ exp_chart_version_map: "{{ exp_chart_version_map | default({}) | combine({item.name: item.version}) }}"
+ with_items:
+ - { name: orc8r, version: "{{service_configs.orc8r_chart_version}}"}
+ - { name: lte-orc8r, version: "{{service_configs.lte_orc8r_chart_version}}" }
+ - { name: feg-orc8r, version: "{{service_configs.feg_orc8r_chart_version}}" }
+ - { name: cwf-orc8r, version: "{{service_configs.cwf_orc8r_chart_version}}" }
+ - { name: fbinternal-orc8r, version: "{{service_configs.fbinternal_orc8r_chart_version}}" }
+ - { name: wifi-orc8r, version: "{{service_configs.wifi_orc8r_chart_version}}" }
+ tags:
+ - install_precheck
+ - upgrade_precheck
+
+- name: Deployment to module mapping
+ set_fact:
+ deployment_module_map: "{{ deployment_module_map | default({}) | combine({item.name: item.modules}) }}"
+ with_items:
+ - { name: fwa, modules: ['orc8r', 'lte-orc8r']}
+ - { name: ffwa, modules: ['orc8r', 'lte-orc8r', 'feg-orc8r'] }
+ - { name: all, modules: ['orc8r', 'lte-orc8r', 'feg-orc8r', 'cwf-orc8r', 'fbinternal-orc8r', 'wifi-orc8r'] }
+ tags:
+ - install_precheck
+ - upgrade_precheck
+
+- name: Validate if necessary charts are present for deployment
+ assert:
+ that: item in chart_version_map
+ fail_msg: "{{item}} chart not found"
+ with_items: "{{deployment_module_map[service_configs.orc8r_deployment_type]}}"
+ tags:
+ - install_precheck
+ - upgrade_precheck
+
+- name: Validate if chart versions present match the expected version
+ assert:
+ that: chart_version_map[item] == exp_chart_version_map[item]
+ fail_msg: "{{item}} chart version mismatch expected version {{exp_chart_version_map[item]}} found version {{chart_version_map[item]}}"
+ with_items: "{{deployment_module_map[service_configs.orc8r_deployment_type]}}"
+ tags:
+ - install_precheck
+ - upgrade_precheck
+
+- name: Remove the test repo
+ ansible.builtin.shell: helm repo remove test
+ ignore_errors: yes
+ tags:
+ - install_precheck
+ - upgrade_precheck
+
+- name: Get list of installed charts
+ ansible.builtin.shell: helm list -o json -n "{{orc8r_namespace}}"
+ register: deployed_chart_info
+ tags: verify_sanity
+
+- name: Verify if charts have been deployed
+ assert:
+ that: item.status == "deployed"
+ fail_msg: "chart {{item.name}} status {{item.status}} not deployed successfully"
+ tags: verify_sanity
+ with_items: "{{deployed_chart_info.stdout}}"
diff --git a/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/services/tasks/main.yml b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/services/tasks/main.yml
new file mode 100644
index 000000000000..166a68035602
--- /dev/null
+++ b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/services/tasks/main.yml
@@ -0,0 +1,35 @@
+- name: Check if required services variables are set
+ ansible.builtin.command: "orcl configure check -c service"
+ register: result
+ failed_when: result.rc != 0
+ tags:
+ - install_precheck
+ - upgrade_precheck
+
+- name: Open configuration file
+ shell: "cat {{ config_dir }}/service.tfvars.json"
+ register: result
+ tags:
+ - install_precheck
+ - upgrade_precheck
+
+- name: Set Service Configs
+ set_fact:
+ service_configs: "{{ result.stdout | from_json }}"
+ tags:
+ - install_precheck
+ - upgrade_precheck
+
+- name: Validate Orc8r deployment type
+ assert:
+ that: service_configs.orc8r_deployment_type in ['fwa', 'ffwa', 'all']
+ fail_msg: 'orc8r_deployment_type can only be one of these options [fwa, ffwa, all]'
+ tags:
+ - install_precheck
+ - upgrade_precheck
+
+- name: Image tasks
+ import_tasks: docker.yml
+
+- name: Helm tasks
+ import_tasks: helm.yml
diff --git a/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/services/vars/all.yml b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/services/vars/all.yml
new file mode 100644
index 000000000000..94189cc57776
--- /dev/null
+++ b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/playbooks/roles/services/vars/all.yml
@@ -0,0 +1,4 @@
+ORC8R_IMAGES:
+ - nginx
+ - controller
+ - magmalte
\ No newline at end of file
diff --git a/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/setup.py b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/setup.py
new file mode 100644
index 000000000000..6e1af6f997b2
--- /dev/null
+++ b/orc8r/cloud/deploy/orc8r_deployer/docker/root/scripts/setup.py
@@ -0,0 +1,28 @@
+"""
+Copyright 2021 The Magma Authors.
+
+This source code is licensed under the BSD-style license found in the
+LICENSE file in the root directory of this source tree.
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+
+from setuptools import setup, find_packages
+
+setup(
+ name='orcl',
+ version='0.1',
+ packages=['cli'],
+ include_package_data=True,
+ install_requires=[
+ 'Click',
+ ],
+ entry_points='''
+ [console_scripts]
+ orcl=cli.orcl:cli
+ ''',
+)
\ No newline at end of file
diff --git a/orc8r/cloud/deploy/orc8r_deployer/docker/root/tf/main.tf.j2 b/orc8r/cloud/deploy/orc8r_deployer/docker/root/tf/main.tf.j2
new file mode 100644
index 000000000000..e2c131375f2a
--- /dev/null
+++ b/orc8r/cloud/deploy/orc8r_deployer/docker/root/tf/main.tf.j2
@@ -0,0 +1,54 @@
+################################################################################
+# Copyright 2020 The Magma Authors.
+
+# This source code is licensed under the BSD-style license found in the
+# LICENSE file in the root directory of this source tree.
+
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+################################################################################
+
+module "orc8r" {
+ source = "/root/magma/orc8r/cloud/deploy/terraform/orc8r-aws"
+
+ {% for k in cfg['infra'] %}
+ {{k}}=var.{{k}}
+ {% endfor %}
+
+ {% for k in cfg['platform'] %}
+ {{k}}=var.{{k}}
+ {% endfor %}
+}
+
+module "orc8r-app" {
+ source = "/root/magma/orc8r/cloud/deploy/terraform/orc8r-helm-aws"
+
+ {% for k in cfg['service'] %}
+ {{k}}=var.{{k}}
+ {% endfor %}
+
+ region = var.region
+ orc8r_domain_name = module.orc8r.orc8r_domain_name
+ orc8r_route53_zone_id = module.orc8r.route53_zone_id
+ external_dns_role_arn = module.orc8r.external_dns_role_arn
+ secretsmanager_orc8r_name = module.orc8r.secretsmanager_secret_name
+
+ orc8r_db_host = module.orc8r.orc8r_db_host
+ orc8r_db_port = module.orc8r.orc8r_db_port
+ orc8r_db_name = module.orc8r.orc8r_db_name
+ orc8r_db_user = module.orc8r.orc8r_db_user
+ orc8r_db_pass = module.orc8r.orc8r_db_pass
+ orc8r_db_dialect = module.orc8r.orc8r_db_dialect
+
+ eks_cluster_id = module.orc8r.eks_cluster_id
+ efs_file_system_id = module.orc8r.efs_file_system_id
+ efs_provisioner_role_arn = module.orc8r.efs_provisioner_role_arn
+ elasticsearch_endpoint = module.orc8r.es_endpoint
+}
+
+output "nameservers" {
+ value = module.orc8r.route53_nameservers
+}
diff --git a/orc8r/cloud/deploy/orc8r_deployer/docker/root/tf/vars.tf.j2 b/orc8r/cloud/deploy/orc8r_deployer/docker/root/tf/vars.tf.j2
new file mode 100644
index 000000000000..52603af3d558
--- /dev/null
+++ b/orc8r/cloud/deploy/orc8r_deployer/docker/root/tf/vars.tf.j2
@@ -0,0 +1,4 @@
+{% for k in cfg %}
+variable "{{k}}" {
+ default = {}
+}{% endfor %}
diff --git a/orc8r/cloud/deploy/orc8r_deployer/docker/run_deployer.bash b/orc8r/cloud/deploy/orc8r_deployer/docker/run_deployer.bash
new file mode 100755
index 000000000000..c8fa5845fa82
--- /dev/null
+++ b/orc8r/cloud/deploy/orc8r_deployer/docker/run_deployer.bash
@@ -0,0 +1,75 @@
+#!/usr/bin/env bash
+set -euf -o pipefail
+
+print_help()
+{
+ echo "
+./run_deployer runs the orc8r deployer container
+orc8r deployer contains scripts which enable user to configure, run prechecks
+install, upgrade, verify and cleanup an orc8r deployment
+Usage: run_deployer [-deploy-dir|-root-dir|-build|-h]
+options:
+-h Print this Help
+-deploy-dir deployment dir containing configs and secrets (mandatory)
+-root-dir magma root directory
+-build build the deployer container
+example: ./run_deployer.bash -deploy-dir /tmp/orc8r_14_deployment"
+}
+
+if (( $# < 2 )); then
+ print_help
+ exit 1
+fi
+
+DOCKER_BUILD=false
+DEPLOY_WORKDIR=
+MAGMA_ROOT=
+while [ -n "${1-}" ]; do
+ case "$1" in
+ -deploy-dir)
+ DEPLOY_WORKDIR="$2"
+ shift
+ ;;
+ -root-dir)
+ MAGMA_ROOT="$2"
+ shift
+ ;;
+ -build)
+ DOCKER_BUILD=true
+ ;;
+ -h)
+ print_help
+ exit;;
+ *) echo "Option $1 not recognized"
+ print_help
+ exit;;
+ esac
+ shift
+done
+
+echo "Build $DOCKER_BUILD"
+
+echo "Deploy workddir $DEPLOY_WORKDIR"
+if [[ ! -d $DEPLOY_WORKDIR ]]; then
+ echo "${DEPLOY_WORKDIR} does not exist. Creating a new directory"
+ mkdir -p $DEPLOY_WORKDIR
+fi
+
+if [ -z $MAGMA_ROOT ]; then
+ SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
+ PATTERN='\/orc8r\/cloud\/deploy\/orc8r_deployer\/docker'
+ MAGMA_ROOT=${SCRIPT_DIR%%$PATTERN}
+ echo "Warning: inferring magma root($MAGMA_ROOT) from run_deployer script directory"
+fi
+
+if $DOCKER_BUILD; then
+ docker build -t orc8r_deployer:latest .
+fi
+
+if [[ $? -eq 0 ]]; then
+ docker run -it \
+ -v "${DEPLOY_WORKDIR}":/root/project \
+ -v "${MAGMA_ROOT}":/root/magma \
+ -v /var/run/docker.sock:/var/run/docker.sock \
+ --rm orc8r_deployer:latest bash
+fi
diff --git a/orc8r/cloud/deploy/terraform/orc8r-aws/README.md b/orc8r/cloud/deploy/terraform/orc8r-aws/README.md
index 88560408b080..0d71af3da4b5 100644
--- a/orc8r/cloud/deploy/terraform/orc8r-aws/README.md
+++ b/orc8r/cloud/deploy/terraform/orc8r-aws/README.md
@@ -52,13 +52,6 @@ Everything below this line was generated by
| elasticsearch\_instance\_type | AWS instance type for ES domain. | `string` | `null` | no |
| elasticsearch\_version | ES version for ES domain. | `string` | `"7.1"` | no |
| global\_tags | n/a | `map` | `{}` | no |
-| nms\_db\_engine\_version | MySQL engine version for NMS DB. | `string` | `"5.7"` | no |
-| nms\_db\_identifier | Identifier for the RDS instance for NMS. | `string` | `"nmsdb"` | no |
-| nms\_db\_instance\_class | RDS instance type for NMS DB. | `string` | `"db.m4.large"` | no |
-| nms\_db\_name | DB name for NMS RDS instance. | `string` | `"magma"` | no |
-| nms\_db\_password | Password for the NMS DB. | `string` | n/a | yes |
-| nms\_db\_storage\_gb | Capacity in GB to allocate for NMS RDS instance. | `number` | `16` | no |
-| nms\_db\_username | Username for default DB user for NMS DB. | `string` | `"magma"` | no |
| orc8r\_db\_engine\_version | Postgres engine version for Orchestrator DB. | `string` | `"9.6.15"` | no |
| orc8r\_db\_identifier | Identifier for the RDS instance for Orchestrator. | `string` | `"orc8rdb"` | no |
| orc8r\_db\_instance\_class | RDS instance type for Orchestrator DB. | `string` | `"db.m4.large"` | no |
@@ -87,10 +80,6 @@ Everything below this line was generated by
| es\_endpoint | Endpoint of the ES cluster if deployed. |
| external\_dns\_role\_arn | IAM role ARN for external-dns |
| kubeconfig | kubectl config file to access the EKS cluster |
-| nms\_db\_host | Hostname of the NMS RDS instance |
-| nms\_db\_name | Database name for NMS RDS instance |
-| nms\_db\_pass | NMS DB password |
-| nms\_db\_user | Database username for NMS RDS instance |
| orc8r\_db\_host | Hostname of the Orchestrator RDS instance |
| orc8r\_db\_name | Database name for Orchestrator RDS instance |
| orc8r\_db\_pass | Orchestrator DB password |
diff --git a/orc8r/cloud/deploy/terraform/orc8r-aws/db.tf b/orc8r/cloud/deploy/terraform/orc8r-aws/db.tf
index 8abdfbde555d..f96fbbffe70c 100644
--- a/orc8r/cloud/deploy/terraform/orc8r-aws/db.tf
+++ b/orc8r/cloud/deploy/terraform/orc8r-aws/db.tf
@@ -31,24 +31,3 @@ resource "aws_db_instance" "default" {
# this won't actually create a final snapshot on destroy
final_snapshot_identifier = "foo"
}
-
-resource "aws_db_instance" "nms" {
- identifier = var.nms_db_identifier
- allocated_storage = var.nms_db_storage_gb
- engine = "mysql"
- engine_version = var.nms_db_engine_version
- instance_class = var.nms_db_instance_class
-
- name = var.nms_db_name
- username = var.nms_db_username
- password = var.nms_db_password
-
- vpc_security_group_ids = [aws_security_group.default.id]
-
- db_subnet_group_name = module.vpc.database_subnet_group
-
- skip_final_snapshot = true
- # we only need this as a placeholder value for `terraform destroy` to work,
- # this won't actually create a final snapshot on destroy
- final_snapshot_identifier = "nms-foo"
-}
diff --git a/orc8r/cloud/deploy/terraform/orc8r-aws/examples/basic/main.tf b/orc8r/cloud/deploy/terraform/orc8r-aws/examples/basic/main.tf
index 9057a4feb4fb..093c541f35e8 100644
--- a/orc8r/cloud/deploy/terraform/orc8r-aws/examples/basic/main.tf
+++ b/orc8r/cloud/deploy/terraform/orc8r-aws/examples/basic/main.tf
@@ -16,7 +16,6 @@ module orc8r {
region = "us-west-2"
- nms_db_password = "Faceb00k12345"
orc8r_db_password = "Faceb00k12345"
secretsmanager_orc8r_secret = "magma-orc8r-test"
deployment_secrets_bucket = "magma.orc8r.test"
diff --git a/orc8r/cloud/deploy/terraform/orc8r-aws/outputs.tf b/orc8r/cloud/deploy/terraform/orc8r-aws/outputs.tf
index e403cc2906ff..9d792fbce38c 100644
--- a/orc8r/cloud/deploy/terraform/orc8r-aws/outputs.tf
+++ b/orc8r/cloud/deploy/terraform/orc8r-aws/outputs.tf
@@ -67,6 +67,11 @@ output "orc8r_db_port" {
value = aws_db_instance.default.port
}
+output "orc8r_db_dialect" {
+ description = "Database dialect for Orchestrator RDS instance"
+ value = var.orc8r_db_dialect
+}
+
output "orc8r_db_user" {
description = "Database username for Orchestrator RDS instance"
value = aws_db_instance.default.username
@@ -78,27 +83,6 @@ output "orc8r_db_pass" {
sensitive = true
}
-output "nms_db_host" {
- description = "Hostname of the NMS RDS instance"
- value = aws_db_instance.nms.address
-}
-
-output "nms_db_name" {
- description = "Database name for NMS RDS instance"
- value = aws_db_instance.nms.name
-}
-
-output "nms_db_user" {
- description = "Database username for NMS RDS instance"
- value = aws_db_instance.nms.username
-}
-
-output "nms_db_pass" {
- description = "NMS DB password"
- value = aws_db_instance.nms.password
- sensitive = true
-}
-
output "route53_zone_id" {
description = "Route53 zone ID for Orchestrator domain name"
value = aws_route53_zone.orc8r.id
diff --git a/orc8r/cloud/deploy/terraform/orc8r-aws/variables.tf b/orc8r/cloud/deploy/terraform/orc8r-aws/variables.tf
index 9c9de1807799..5f901ecc949b 100644
--- a/orc8r/cloud/deploy/terraform/orc8r-aws/variables.tf
+++ b/orc8r/cloud/deploy/terraform/orc8r-aws/variables.tf
@@ -239,49 +239,10 @@ variable "orc8r_db_engine_version" {
default = "9.6.15"
}
-##############################################################################
-# NMS DB Specs
-##############################################################################
-
-variable "nms_db_identifier" {
- description = "Identifier for the RDS instance for NMS."
- type = string
- default = "nmsdb"
-}
-
-variable "nms_db_storage_gb" {
- description = "Capacity in GB to allocate for NMS RDS instance."
- type = number
- default = 16
-}
-
-variable "nms_db_instance_class" {
- description = "RDS instance type for NMS DB."
- type = string
- default = "db.m4.large"
-}
-
-variable "nms_db_name" {
- description = "DB name for NMS RDS instance."
- type = string
- default = "magma"
-}
-
-variable "nms_db_username" {
- description = "Username for default DB user for NMS DB."
- type = string
- default = "magma"
-}
-
-variable "nms_db_password" {
- description = "Password for the NMS DB. Must be at least 8 characters."
- type = string
-}
-
-variable "nms_db_engine_version" {
- description = "MySQL engine version for NMS DB."
+variable "orc8r_db_dialect" {
+ description = "Database dialect for Orchestrator DB."
type = string
- default = "5.7"
+ default = "postgres"
}
##############################################################################
diff --git a/orc8r/cloud/deploy/terraform/orc8r-helm-aws/README.md b/orc8r/cloud/deploy/terraform/orc8r-helm-aws/README.md
index 01a43af6d609..6cd16e582cb1 100644
--- a/orc8r/cloud/deploy/terraform/orc8r-helm-aws/README.md
+++ b/orc8r/cloud/deploy/terraform/orc8r-helm-aws/README.md
@@ -53,10 +53,6 @@ Everything below this line was generated by
| install\_tiller | Install Tiller in the cluster or not. | `bool` | `true` | no |
| lte_orc8r\_chart\_version | Version of the Orchestrator lte module Helm chart to install. | `string` | 0.2.1 | yes |
| monitoring\_kubernetes\_namespace | K8s namespace to install Orchestrator monitoring components into. | `string` | `"monitoring"` | no |
-| nms\_db\_host | DB hostname for NMS database connection. | `string` | n/a | yes |
-| nms\_db\_name | DB name for NMS database connection. | `string` | n/a | yes |
-| nms\_db\_pass | NMS DB password. | `string` | n/a | yes |
-| nms\_db\_user | DB username for NMS database connection. | `string` | n/a | yes |
| orc8r\_chart\_version | Version of the core Orchestrator Helm chart to install. | `string` | 1.5.8 | yes |
| orc8r\_controller\_replicas | Replica count for Orchestrator controller pods. | `number` | `2` | no |
| orc8r\_db\_host | DB hostname for Orchestrator database connection. | `string` | n/a | yes |
diff --git a/orc8r/cloud/deploy/terraform/orc8r-helm-aws/efs.tf b/orc8r/cloud/deploy/terraform/orc8r-helm-aws/efs.tf
index 3c893fda7cfb..6c1acf2128a4 100644
--- a/orc8r/cloud/deploy/terraform/orc8r-helm-aws/efs.tf
+++ b/orc8r/cloud/deploy/terraform/orc8r-helm-aws/efs.tf
@@ -13,7 +13,7 @@
# k8s requires provisioner to treat efs as a persistent volume
resource "helm_release" "efs_provisioner" {
- name = "efs-provisioner"
+ name = var.efs_provisioner_name
repository = local.stable_helm_repo
chart = "efs-provisioner"
version = "0.11.0"
@@ -27,7 +27,7 @@ resource "helm_release" "efs_provisioner" {
path: /pv-volume
provisionerName: aws-efs
storageClass:
- name: efs
+ name: ${var.efs_storage_class_name}
podAnnotations:
iam-assumable-role: ${var.efs_provisioner_role_arn}
VALUES
diff --git a/orc8r/cloud/deploy/terraform/orc8r-helm-aws/examples/basic/main.tf b/orc8r/cloud/deploy/terraform/orc8r-helm-aws/examples/basic/main.tf
index 64504b6f1e49..82f56d3931b8 100644
--- a/orc8r/cloud/deploy/terraform/orc8r-helm-aws/examples/basic/main.tf
+++ b/orc8r/cloud/deploy/terraform/orc8r-helm-aws/examples/basic/main.tf
@@ -17,7 +17,6 @@ module "orc8r" {
region = "us-west-2"
- nms_db_password = "mypassword" # must be at least 8 characters
orc8r_db_password = "mypassword" # must be at least 8 characters
secretsmanager_orc8r_secret = "orc8r-secrets"
orc8r_domain_name = "orc8r.example.com"
@@ -50,15 +49,12 @@ module "orc8r-app" {
secretsmanager_orc8r_name = module.orc8r.secretsmanager_secret_name
seed_certs_dir = "~/secrets/certs"
- orc8r_db_host = module.orc8r.orc8r_db_host
- orc8r_db_name = module.orc8r.orc8r_db_name
- orc8r_db_user = module.orc8r.orc8r_db_user
- orc8r_db_pass = module.orc8r.orc8r_db_pass
-
- nms_db_host = module.orc8r.nms_db_host
- nms_db_name = module.orc8r.nms_db_name
- nms_db_user = module.orc8r.nms_db_user
- nms_db_pass = module.orc8r.nms_db_pass
+ orc8r_db_host = module.orc8r.orc8r_db_host
+ orc8r_db_port = module.orc8r.orc8r_db_port
+ orc8r_db_dialect = module.orc8r.orc8r_db_dialect
+ orc8r_db_name = module.orc8r.orc8r_db_name
+ orc8r_db_user = module.orc8r.orc8r_db_user
+ orc8r_db_pass = module.orc8r.orc8r_db_pass
# Note that this can be any container registry provider -- the example below
# provides the URL format for Docker Hub, where the user and pass are your
diff --git a/orc8r/cloud/deploy/terraform/orc8r-helm-aws/examples/online-upgrade/README.md b/orc8r/cloud/deploy/terraform/orc8r-helm-aws/examples/online-upgrade/README.md
index 77111cc6cad0..a85c0e47fa7a 100644
--- a/orc8r/cloud/deploy/terraform/orc8r-helm-aws/examples/online-upgrade/README.md
+++ b/orc8r/cloud/deploy/terraform/orc8r-helm-aws/examples/online-upgrade/README.md
@@ -48,8 +48,6 @@ https://magma.github.io/magma.
| helm\_user | Username for your Helm repo | `string` | n/a | yes |
| metrics\_worker\_subnet\_id | Subnet ID of the metrics worker instance. Find this in the EC2 console (the instance will have the tag orc8r-node-type: orc8r-prometheus-node). | `string` | n/a | yes |
| new\_deployment\_name | New name for the v1.1.0 Helm deployment. This must be different than your old v1.0 deployment (which was probably 'orc8r') | `string` | n/a | yes |
-| nms\_db\_configuration | Configuration of the NMS MySQL instance. This should match the v1.0 Terraform. | object({ identifier = string storage_gb = number engine_version = string instance_class = string }) | { "engine_version": "5.7", "identifier": "nmsdb", "instance_class": "db.m4.large", "storage_gb": 16 } | no |
-| nms\_db\_password | Password for the NMS MySQL instance. This should match the v1.0 Terraform. | `string` | n/a | yes |
| orc8r\_chart\_version | Chart version for the Helm deployment | `string` | `"1.4.21"` | no |
| orc8r\_container\_tag | Container tag to deploy | `string` | n/a | yes |
| orc8r\_controller\_replicas | How many controller pod replicas to deploy | `number` | `2` | no |
diff --git a/orc8r/cloud/deploy/terraform/orc8r-helm-aws/examples/online-upgrade/main.tf b/orc8r/cloud/deploy/terraform/orc8r-helm-aws/examples/online-upgrade/main.tf
index d7930b78a339..73a0d9731618 100644
--- a/orc8r/cloud/deploy/terraform/orc8r-helm-aws/examples/online-upgrade/main.tf
+++ b/orc8r/cloud/deploy/terraform/orc8r-helm-aws/examples/online-upgrade/main.tf
@@ -29,11 +29,6 @@ module orc8r {
orc8r_db_engine_version = var.orc8r_db_configuration.engine_version
orc8r_db_instance_class = var.orc8r_db_configuration.instance_class
orc8r_db_password = var.orc8r_db_password
- nms_db_identifier = var.nms_db_configuration.identifier
- nms_db_storage_gb = var.nms_db_configuration.storage_gb
- nms_db_engine_version = var.nms_db_configuration.engine_version
- nms_db_instance_class = var.nms_db_configuration.instance_class
- nms_db_password = var.nms_db_password
secretsmanager_orc8r_secret = var.secretsmanager_secret_name
@@ -118,15 +113,11 @@ module orc8r-app {
existing_tiller_service_account_name = "tiller"
helm_deployment_name = var.new_deployment_name
- orc8r_db_host = module.orc8r.orc8r_db_host
- orc8r_db_name = module.orc8r.orc8r_db_name
- orc8r_db_user = module.orc8r.orc8r_db_user
- orc8r_db_pass = module.orc8r.orc8r_db_pass
-
- nms_db_host = module.orc8r.nms_db_host
- nms_db_name = module.orc8r.nms_db_name
- nms_db_user = module.orc8r.nms_db_user
- nms_db_pass = module.orc8r.nms_db_pass
+ orc8r_db_host = module.orc8r.orc8r_db_host
+ orc8r_db_dialect = module.orc8r.orc8r_db_dialect
+ orc8r_db_name = module.orc8r.orc8r_db_name
+ orc8r_db_user = module.orc8r.orc8r_db_user
+ orc8r_db_pass = module.orc8r.orc8r_db_pass
docker_registry = var.docker_registry
docker_user = var.docker_user
diff --git a/orc8r/cloud/deploy/terraform/orc8r-helm-aws/examples/online-upgrade/variables.tf b/orc8r/cloud/deploy/terraform/orc8r-helm-aws/examples/online-upgrade/variables.tf
index 5be3a3def00a..a7fbca7a8911 100644
--- a/orc8r/cloud/deploy/terraform/orc8r-helm-aws/examples/online-upgrade/variables.tf
+++ b/orc8r/cloud/deploy/terraform/orc8r-helm-aws/examples/online-upgrade/variables.tf
@@ -51,27 +51,6 @@ variable "orc8r_db_password" {
type = string
}
-variable "nms_db_configuration" {
- description = "Configuration of the NMS MySQL instance. This should match the v1.0 Terraform."
- type = object({
- identifier = string
- storage_gb = number
- engine_version = string
- instance_class = string
- })
- default = {
- identifier = "nmsdb"
- storage_gb = 16
- engine_version = "5.7"
- instance_class = "db.m4.large"
- }
-}
-
-variable "nms_db_password" {
- description = "Password for the NMS MySQL instance. This should match the v1.0 Terraform."
- type = string
-}
-
variable "secretsmanager_secret_name" {
description = "Name for the Secretsmanager secret that the orc8r-aws module will create."
type = string
diff --git a/orc8r/cloud/deploy/terraform/orc8r-helm-aws/examples/remote/main.tf b/orc8r/cloud/deploy/terraform/orc8r-helm-aws/examples/remote/main.tf
index bd7a1e988b3c..636eb1a1c7cb 100644
--- a/orc8r/cloud/deploy/terraform/orc8r-helm-aws/examples/remote/main.tf
+++ b/orc8r/cloud/deploy/terraform/orc8r-helm-aws/examples/remote/main.tf
@@ -47,7 +47,6 @@ resource "aws_dynamodb_table" "terraform_locks" {
# This secretsmanager secret needs to be manually created and populated in the
# AWS console. For this example, you would set the following key-value pairs:
-# nms_db_pass
# orc8r_db_pass
# docker_registry
# docker_user
@@ -69,7 +68,6 @@ module "orc8r" {
region = local.region
- nms_db_password = jsondecode(data.aws_secretsmanager_secret_version.root_secrets.secret_string)["nms_db_pass"]
orc8r_db_password = jsondecode(data.aws_secretsmanager_secret_version.root_secrets.secret_string)["orc8r_db_pass"]
secretsmanager_orc8r_secret = "orc8r-secrets"
orc8r_domain_name = "orc8r.example.com"
@@ -113,15 +111,12 @@ module "orc8r-app" {
secretsmanager_orc8r_name = module.orc8r.secretsmanager_secret_name
seed_certs_dir = "~/orc8r.test.secrets/certs"
- orc8r_db_host = module.orc8r.orc8r_db_host
- orc8r_db_name = module.orc8r.orc8r_db_name
- orc8r_db_user = module.orc8r.orc8r_db_user
- orc8r_db_pass = module.orc8r.orc8r_db_pass
-
- nms_db_host = module.orc8r.nms_db_host
- nms_db_name = module.orc8r.nms_db_name
- nms_db_user = module.orc8r.nms_db_user
- nms_db_pass = module.orc8r.nms_db_pass
+ orc8r_db_host = module.orc8r.orc8r_db_host
+ orc8r_db_port = module.orc8r.orc8r_db_port
+ orc8r_db_dialect = module.orc8r.orc8r_db_dialect
+ orc8r_db_name = module.orc8r.orc8r_db_name
+ orc8r_db_user = module.orc8r.orc8r_db_user
+ orc8r_db_pass = module.orc8r.orc8r_db_pass
docker_registry = jsondecode(data.aws_secretsmanager_secret_version.root_secrets.secret_string)["docker_registry"]
docker_user = jsondecode(data.aws_secretsmanager_secret_version.root_secrets.secret_string)["docker_user"]
diff --git a/orc8r/cloud/deploy/terraform/orc8r-helm-aws/k8s.tf b/orc8r/cloud/deploy/terraform/orc8r-helm-aws/k8s.tf
index 2a4ff76333ac..dfe366e06166 100644
--- a/orc8r/cloud/deploy/terraform/orc8r-helm-aws/k8s.tf
+++ b/orc8r/cloud/deploy/terraform/orc8r-helm-aws/k8s.tf
@@ -25,7 +25,7 @@ resource "kubernetes_namespace" "monitoring" {
# external dns maps route53 to ingress resources
resource "helm_release" "external_dns" {
- name = "external-dns"
+ name = var.external_dns_deployment_name
repository = local.stable_helm_repo
chart = "external-dns"
version = "2.19.1"
diff --git a/orc8r/cloud/deploy/terraform/orc8r-helm-aws/logging.tf b/orc8r/cloud/deploy/terraform/orc8r-helm-aws/logging.tf
index c38b3e4a407d..bbb8f09ca336 100644
--- a/orc8r/cloud/deploy/terraform/orc8r-helm-aws/logging.tf
+++ b/orc8r/cloud/deploy/terraform/orc8r-helm-aws/logging.tf
@@ -18,7 +18,7 @@ locals {
resource "helm_release" "fluentd" {
count = var.elasticsearch_endpoint == null ? 0 : 1
- name = "fluentd"
+ name = var.fluentd_deployment_name
namespace = kubernetes_namespace.orc8r.metadata[0].name
repository = local.stable_helm_repo
chart = "fluentd"
@@ -130,7 +130,7 @@ resource "helm_release" "fluentd" {
resource "helm_release" "elasticsearch_curator" {
count = var.elasticsearch_endpoint == null ? 0 : 1
- name = "elasticsearch-curator"
+ name = var.elasticsearch_curator_name
repository = local.stable_helm_repo
chart = "elasticsearch-curator"
namespace = kubernetes_namespace.monitoring.metadata[0].name
diff --git a/orc8r/cloud/deploy/terraform/orc8r-helm-aws/main.tf b/orc8r/cloud/deploy/terraform/orc8r-helm-aws/main.tf
index 201679b93a1a..20470e35940b 100644
--- a/orc8r/cloud/deploy/terraform/orc8r-helm-aws/main.tf
+++ b/orc8r/cloud/deploy/terraform/orc8r-helm-aws/main.tf
@@ -40,11 +40,6 @@ resource "helm_release" "orc8r" {
name = "controller.spec.database.pass"
value = var.orc8r_db_pass
}
-
- set_sensitive {
- name = "nms.magmalte.env.mysql_pass"
- value = var.nms_db_pass
- }
}
resource "helm_release" "lte-orc8r" {
@@ -69,11 +64,6 @@ resource "helm_release" "lte-orc8r" {
name = "controller.spec.database.pass"
value = var.orc8r_db_pass
}
-
- set_sensitive {
- name = "nms.magmalte.env.mysql_pass"
- value = var.nms_db_pass
- }
}
resource "helm_release" "feg-orc8r" {
@@ -97,11 +87,6 @@ resource "helm_release" "feg-orc8r" {
name = "controller.spec.database.pass"
value = var.orc8r_db_pass
}
-
- set_sensitive {
- name = "nms.magmalte.env.mysql_pass"
- value = var.nms_db_pass
- }
}
resource "helm_release" "cwf-orc8r" {
@@ -121,11 +106,6 @@ resource "helm_release" "cwf-orc8r" {
name = "controller.spec.database.pass"
value = var.orc8r_db_pass
}
-
- set_sensitive {
- name = "nms.magmalte.env.mysql_pass"
- value = var.nms_db_pass
- }
}
@@ -147,11 +127,6 @@ resource "helm_release" "fbinternal-orc8r" {
name = "controller.spec.database.pass"
value = var.orc8r_db_pass
}
-
- set_sensitive {
- name = "nms.magmalte.env.mysql_pass"
- value = var.nms_db_pass
- }
}
resource "helm_release" "wifi-orc8r" {
@@ -172,11 +147,6 @@ resource "helm_release" "wifi-orc8r" {
name = "controller.spec.database.pass"
value = var.orc8r_db_pass
}
-
- set_sensitive {
- name = "nms.magmalte.env.mysql_pass"
- value = var.nms_db_pass
- }
}
@@ -203,15 +173,14 @@ data "template_file" "orc8r_values" {
api_hostname = format("api.%s", var.orc8r_domain_name)
nms_hostname = format("*.nms.%s", var.orc8r_domain_name)
- orc8r_db_name = var.orc8r_db_name
- orc8r_db_host = var.orc8r_db_host
- orc8r_db_port = var.orc8r_db_port
- orc8r_db_user = var.orc8r_db_user
+ orc8r_db_name = var.orc8r_db_name
+ orc8r_db_host = var.orc8r_db_host
+ orc8r_db_port = var.orc8r_db_port
+ orc8r_db_dialect = var.orc8r_db_dialect
+ orc8r_db_user = var.orc8r_db_user
+ orc8r_db_pass = var.orc8r_db_pass
deploy_nms = var.deploy_nms
- nms_db_name = var.nms_db_name
- nms_db_host = var.nms_db_host
- nms_db_user = var.nms_db_user
metrics_pvc_promcfg = kubernetes_persistent_volume_claim.storage["promcfg"].metadata.0.name
metrics_pvc_promdata = kubernetes_persistent_volume_claim.storage["promdata"].metadata.0.name
diff --git a/orc8r/cloud/deploy/terraform/orc8r-helm-aws/storage.tf b/orc8r/cloud/deploy/terraform/orc8r-helm-aws/storage.tf
index 44be3da08907..c45b33c4b237 100644
--- a/orc8r/cloud/deploy/terraform/orc8r-helm-aws/storage.tf
+++ b/orc8r/cloud/deploy/terraform/orc8r-helm-aws/storage.tf
@@ -55,7 +55,7 @@ resource "kubernetes_persistent_volume_claim" "storage" {
storage = each.value.storage
}
}
- storage_class_name = "efs"
+ storage_class_name = var.efs_storage_class_name
}
depends_on = [helm_release.efs_provisioner]
diff --git a/orc8r/cloud/deploy/terraform/orc8r-helm-aws/templates/orc8r-values.tpl b/orc8r/cloud/deploy/terraform/orc8r-helm-aws/templates/orc8r-values.tpl
index 1ec4d8439b9c..505cf89af8e9 100644
--- a/orc8r/cloud/deploy/terraform/orc8r-helm-aws/templates/orc8r-values.tpl
+++ b/orc8r/cloud/deploy/terraform/orc8r-helm-aws/templates/orc8r-values.tpl
@@ -183,9 +183,12 @@ nms:
env:
api_host: ${api_hostname}
- mysql_db: ${nms_db_name}
- mysql_host: ${nms_db_host}
- mysql_user: ${nms_db_user}
+ mysql_db: ${orc8r_db_name}
+ mysql_dialect: ${orc8r_db_dialect}
+ mysql_host: ${orc8r_db_host}
+ mysql_port: ${orc8r_db_port}
+ mysql_user: ${orc8r_db_user}
+ mysql_pass: ${orc8r_db_pass}
grafana_address: ${user_grafana_hostname}
nginx:
diff --git a/orc8r/cloud/deploy/terraform/orc8r-helm-aws/variables.tf b/orc8r/cloud/deploy/terraform/orc8r-helm-aws/variables.tf
index c490b49ca40f..8fbd71d73a32 100644
--- a/orc8r/cloud/deploy/terraform/orc8r-helm-aws/variables.tf
+++ b/orc8r/cloud/deploy/terraform/orc8r-helm-aws/variables.tf
@@ -43,6 +43,12 @@ variable "orc8r_route53_zone_id" {
type = string
}
+variable "external_dns_deployment_name" {
+ description = "Name of the external dns helm deployment"
+ type = string
+ default = "external-dns"
+}
+
variable "external_dns_role_arn" {
description = "IAM role ARN for ExternalDNS."
type = string
@@ -96,6 +102,11 @@ variable "orc8r_db_name" {
type = string
}
+variable "orc8r_db_dialect" {
+ description = "DB dialect for Orchestrator database connection."
+ type = string
+}
+
variable "orc8r_db_host" {
description = "DB hostname for Orchestrator database connection."
type = string
@@ -112,21 +123,6 @@ variable "orc8r_db_user" {
type = string
}
-variable "nms_db_name" {
- description = "DB name for NMS database connection."
- type = string
-}
-
-variable "nms_db_host" {
- description = "DB hostname for NMS database connection."
- type = string
-}
-
-variable "nms_db_user" {
- description = "DB username for NMS database connection."
- type = string
-}
-
##############################################################################
# Helm configuration
##############################################################################
@@ -171,7 +167,7 @@ variable "orc8r_deployment_type" {
variable "orc8r_chart_version" {
description = "Version of the core orchestrator Helm chart to install."
type = string
- default = "1.5.18"
+ default = "1.5.19"
}
variable "cwf_orc8r_chart_version" {
@@ -224,6 +220,18 @@ variable "efs_provisioner_role_arn" {
type = string
}
+variable "efs_provisioner_name" {
+ description = "Name of the efs provisioner helm deployment"
+ type = string
+ default = "efs-provisioner"
+}
+
+variable "efs_storage_class_name" {
+ description = "Name of the Storage class"
+ type = string
+ default = "efs"
+}
+
##############################################################################
# Log aggregation configuration
##############################################################################
@@ -258,6 +266,18 @@ variable "elasticsearch_curator_log_level" {
default = "INFO"
}
+variable "elasticsearch_curator_name" {
+ description = "Name of the elasticsearch-curator helm deployment"
+ type = string
+ default = "elasticsearch-curator"
+}
+
+variable "fluentd_deployment_name" {
+ description = "Name of the fluentd helm deployment"
+ type = string
+ default = "fluentd"
+}
+
##############################################################################
# Secret configuration and values
##############################################################################
@@ -272,11 +292,6 @@ variable "orc8r_db_pass" {
type = string
}
-variable "nms_db_pass" {
- description = "NMS DB password."
- type = string
-}
-
variable "docker_registry" {
description = "Docker registry to pull Orchestrator containers from."
type = string
diff --git a/orc8r/cloud/docker/controller/supervisord.conf b/orc8r/cloud/docker/controller/supervisord.conf
index c9e9fbda3c59..f22bf3bd4320 100644
--- a/orc8r/cloud/docker/controller/supervisord.conf
+++ b/orc8r/cloud/docker/controller/supervisord.conf
@@ -269,3 +269,11 @@ stdout_logfile=NONE
stderr_logfile=NONE
stdout_events_enabled=true
stderr_events_enabled=true
+
+[program:nprobe]
+command=/usr/bin/envdir /var/opt/magma/envdir /var/opt/magma/bin/nprobe -run_echo_server=true -logtostderr=true -v=0
+autorestart=true
+stdout_logfile=NONE
+stderr_logfile=NONE
+stdout_events_enabled=true
+stderr_events_enabled=true
diff --git a/orc8r/cloud/docker/nginx/templates/nginx.conf.j2 b/orc8r/cloud/docker/nginx/templates/nginx.conf.j2
index 34c03858bfbc..1e0f90afba1b 100644
--- a/orc8r/cloud/docker/nginx/templates/nginx.conf.j2
+++ b/orc8r/cloud/docker/nginx/templates/nginx.conf.j2
@@ -133,7 +133,7 @@ http {
if ($srv ~* "(\w+)[_](\w+)") {
set $srv "$1-$2";
}
- grpc_pass grpc://orc8r-$srv.{{ backend }}:9180;
+ grpc_pass grpc://orc8r-bootstrapper.{{ backend }}:9180;
{%- else %}
grpc_pass grpc://{{ backend }}:$open_srvport;
{%- endif %}
diff --git a/orc8r/cloud/go/obsidian/swagger/v1/swagger.yml b/orc8r/cloud/go/obsidian/swagger/v1/swagger.yml
index a1368c7a713f..8287d991e4fd 100644
--- a/orc8r/cloud/go/obsidian/swagger/v1/swagger.yml
+++ b/orc8r/cloud/go/obsidian/swagger/v1/swagger.yml
@@ -3203,6 +3203,156 @@ paths:
summary: Update the name of an LTE network
tags:
- LTE Networks
+ /lte/{network_id}/network_probe/destinations:
+ get:
+ parameters:
+ - $ref: '#/parameters/network_id'
+ responses:
+ "200":
+ description: Provisioned NetworkProbe Destinations
+ schema:
+ $ref: '#/definitions/network_probe_destination'
+ default:
+ $ref: '#/responses/UnexpectedError'
+ summary: List NetworkProbe Destinations in the network
+ tags:
+ - Network Probes
+ post:
+ parameters:
+ - $ref: '#/parameters/network_id'
+ - in: body
+ name: network_probe_destination
+ required: true
+ schema:
+ $ref: '#/definitions/network_probe_destination'
+ responses:
+ "201":
+ description: Success
+ default:
+ $ref: '#/responses/UnexpectedError'
+ summary: Add a new NetworkProbeDestination to the network
+ tags:
+ - Network Probes
+ /lte/{network_id}/network_probe/destinations/{destination_id}:
+ delete:
+ parameters:
+ - $ref: '#/parameters/network_id'
+ - $ref: '#/parameters/destination_id'
+ responses:
+ "204":
+ description: Success
+ default:
+ $ref: '#/responses/UnexpectedError'
+ summary: Remove a NetworkProbe Destination from the network
+ tags:
+ - Network Probes
+ get:
+ parameters:
+ - $ref: '#/parameters/network_id'
+ - $ref: '#/parameters/destination_id'
+ responses:
+ "200":
+ description: NetworkProbeDestination Info
+ schema:
+ $ref: '#/definitions/network_probe_destination'
+ default:
+ $ref: '#/responses/UnexpectedError'
+ summary: Retrieve a NetworkProbe Destination
+ tags:
+ - Network Probes
+ put:
+ parameters:
+ - $ref: '#/parameters/network_id'
+ - $ref: '#/parameters/destination_id'
+ - description: New NetworkProbeDestination configuration
+ in: body
+ name: network_probe_destination
+ required: true
+ schema:
+ $ref: '#/definitions/network_probe_destination'
+ responses:
+ "204":
+ description: Success
+ default:
+ $ref: '#/responses/UnexpectedError'
+ summary: Update an existing NetworkProbe Destination in the network
+ tags:
+ - Network Probes
+ /lte/{network_id}/network_probe/tasks:
+ get:
+ parameters:
+ - $ref: '#/parameters/network_id'
+ responses:
+ "200":
+ description: Provisioned NetworkProbeTasks
+ schema:
+ $ref: '#/definitions/network_probe_task'
+ default:
+ $ref: '#/responses/UnexpectedError'
+ summary: List NetworkProbeTask in the network
+ tags:
+ - Network Probes
+ post:
+ parameters:
+ - $ref: '#/parameters/network_id'
+ - in: body
+ name: network_probe_task
+ required: true
+ schema:
+ $ref: '#/definitions/network_probe_task'
+ responses:
+ "201":
+ description: Success
+ default:
+ $ref: '#/responses/UnexpectedError'
+ summary: Add a new NetworkProbeTask to the network
+ tags:
+ - Network Probes
+ /lte/{network_id}/network_probe/tasks/{task_id}:
+ delete:
+ parameters:
+ - $ref: '#/parameters/network_id'
+ - $ref: '#/parameters/task_id'
+ responses:
+ "204":
+ description: Success
+ default:
+ $ref: '#/responses/UnexpectedError'
+ summary: Remove an NetworkProbeTask from the network
+ tags:
+ - Network Probes
+ get:
+ parameters:
+ - $ref: '#/parameters/network_id'
+ - $ref: '#/parameters/task_id'
+ responses:
+ "200":
+ description: NetworkProbeTask Info
+ schema:
+ $ref: '#/definitions/network_probe_task'
+ default:
+ $ref: '#/responses/UnexpectedError'
+ summary: Retrieve the NetworkProbeTask info
+ tags:
+ - Network Probes
+ put:
+ parameters:
+ - $ref: '#/parameters/network_id'
+ - $ref: '#/parameters/task_id'
+ - description: New NetworkProbeTask configuration
+ in: body
+ name: network_probe_task
+ required: true
+ schema:
+ $ref: '#/definitions/network_probe_task'
+ responses:
+ "204":
+ description: Success
+ default:
+ $ref: '#/responses/UnexpectedError'
+ summary: Update an existing NetworkProbeTask in the network
+ tags:
+ - Network Probes
/lte/{network_id}/policy_qos_profiles:
get:
parameters:
@@ -6543,6 +6693,12 @@ parameters:
name: channel_id
required: true
type: string
+ destination_id:
+ description: Network Probe Destination ID
+ in: path
+ name: destination_id
+ required: true
+ type: string
dns_domain:
description: DNS record domain
in: path
@@ -6657,6 +6813,12 @@ parameters:
name: subscriber_id
required: true
type: string
+ task_id:
+ description: Network Probe Task ID
+ in: path
+ name: task_id
+ required: true
+ type: string
tenant_id:
description: Tenant ID
in: path
@@ -9928,6 +10090,93 @@ definitions:
minLength: 1
type: string
x-nullable: false
+ network_probe_destination:
+ description: Network Probe Destination
+ properties:
+ destination_details:
+ $ref: '#/definitions/network_probe_destination_details'
+ destination_id:
+ $ref: '#/definitions/network_probe_destination_id'
+ required:
+ - destination_id
+ - destination_details
+ type: object
+ network_probe_destination_details:
+ properties:
+ delivery_address:
+ example: 127.0.0.1:4040
+ type: string
+ x-nullable: false
+ delivery_type:
+ enum:
+ - all
+ - events_only
+ example: events_only
+ type: string
+ x-nullable: false
+ required:
+ - delivery_type
+ - delivery_address
+ type: object
+ network_probe_destination_id:
+ example: xxxx-yyyy-zzzz
+ type: string
+ x-nullable: false
+ network_probe_task:
+ description: Network Probe Task
+ properties:
+ task_details:
+ $ref: '#/definitions/network_probe_task_details'
+ task_id:
+ $ref: '#/definitions/network_probe_task_id'
+ required:
+ - task_id
+ - task_details
+ type: object
+ network_probe_task_details:
+ properties:
+ correlation_id:
+ example: 605394647632969700
+ format: uint64
+ type: integer
+ delivery_type:
+ enum:
+ - all
+ - events_only
+ example: events_only
+ type: string
+ x-nullable: false
+ duration:
+ default: 0
+ description: the duration in seconds after which the task will expire.
+ example: 300
+ minimum: 0
+ type: integer
+ target_id:
+ type: string
+ x-nullable: false
+ target_type:
+ enum:
+ - imsi
+ - imei
+ - msisdn
+ example: imsi
+ type: string
+ x-nullable: false
+ timestamp:
+ description: The timestamp in ISO 8601 format
+ example: "2020-03-11T00:36:59.65Z"
+ format: date-time
+ type: string
+ required:
+ - target_id
+ - target_type
+ - delivery_type
+ type: object
+ network_probe_task_id:
+ example: imsi1023001
+ type: string
+ x-nullable: false
network_ran_configs:
description: RAN (radio access network) cellular configuration for a network
minLength: 1
diff --git a/orc8r/cloud/go/services/ctraced/ctraced/main.go b/orc8r/cloud/go/services/ctraced/ctraced/main.go
index 38c55418f8d7..f0f912d92ffc 100644
--- a/orc8r/cloud/go/services/ctraced/ctraced/main.go
+++ b/orc8r/cloud/go/services/ctraced/ctraced/main.go
@@ -22,9 +22,11 @@ import (
"magma/orc8r/cloud/go/service"
"magma/orc8r/cloud/go/services/ctraced"
"magma/orc8r/cloud/go/services/ctraced/obsidian/handlers"
+ "magma/orc8r/cloud/go/services/ctraced/servicers"
ctraced_storage "magma/orc8r/cloud/go/services/ctraced/storage"
"magma/orc8r/cloud/go/sqorc"
"magma/orc8r/cloud/go/storage"
+ "magma/orc8r/lib/go/protos"
"github.com/golang/glog"
)
@@ -33,29 +35,31 @@ func main() {
// Create service
srv, err := service.NewOrchestratorService(orc8r.ModuleName, ctraced.ServiceName)
if err != nil {
- glog.Fatalf("Error creating ctraced service: %s", err)
+ glog.Fatalf("Error creating ctraced service: %+v", err)
}
- swagger_protos.RegisterSwaggerSpecServer(srv.GrpcServer, swagger.NewSpecServicerFromFile(ctraced.ServiceName))
-
// Init storage
db, err := sqorc.Open(storage.SQLDriver, storage.DatabaseSource)
if err != nil {
- glog.Fatalf("Error opening db connection: %v", err)
+ glog.Fatalf("Error opening db connection: %+v", err)
}
fact := blobstore.NewSQLBlobStorageFactory(ctraced.LookupTableBlobstore, db, sqorc.GetSqlBuilder())
err = fact.InitializeFactory()
if err != nil {
- glog.Fatalf("Error initializing ctraced table: %v", err)
+ glog.Fatalf("Error initializing ctraced table: %+v", err)
}
ctracedBlobstore := ctraced_storage.NewCtracedBlobstore(fact)
+ // Init gRPC servicer
+ protos.RegisterCallTraceControllerServer(srv.GrpcServer, servicers.NewCallTraceServicer(ctracedBlobstore))
+ swagger_protos.RegisterSwaggerSpecServer(srv.GrpcServer, swagger.NewSpecServicerFromFile(ctraced.ServiceName))
+
gwClient := handlers.NewGwCtracedClient()
obsidian.AttachHandlers(srv.EchoServer, handlers.GetObsidianHandlers(gwClient, ctracedBlobstore))
// Run service
err = srv.Run()
if err != nil {
- glog.Fatalf("Error running ctraced service: %s", err)
+ glog.Fatalf("Error running ctraced service: %+v", err)
}
}
diff --git a/orc8r/cloud/go/services/ctraced/obsidian/handlers/handlers.go b/orc8r/cloud/go/services/ctraced/obsidian/handlers/handlers.go
index c4a93e2c4268..c92df2df5bcf 100644
--- a/orc8r/cloud/go/services/ctraced/obsidian/handlers/handlers.go
+++ b/orc8r/cloud/go/services/ctraced/obsidian/handlers/handlers.go
@@ -158,7 +158,9 @@ func getUpdateCallTraceHandlerFunc(client GwCtracedClient, storage storage.Ctrac
return obsidian.HttpError(errors.New("Error: call trace end already triggered earlier"), http.StatusBadRequest)
}
- req := &protos.EndTraceRequest{}
+ req := &protos.EndTraceRequest{
+ TraceId: callTraceID,
+ }
resp, err := client.EndCallTrace(networkID, callTrace.Config.GatewayID, req)
if err != nil {
return err
@@ -256,7 +258,9 @@ func getNetworkIDAndCallTraceID(c echo.Context) (string, string, *echo.HTTPError
func buildStartTraceRequest(cfg *models.CallTraceConfig) (*protos.StartTraceRequest, error) {
req := &protos.StartTraceRequest{
+ TraceId: cfg.TraceID,
TraceType: protos.StartTraceRequest_ALL,
+ Timeout: cfg.Timeout,
CaptureFilters: cfg.CaptureFilters,
DisplayFilters: cfg.DisplayFilters,
}
diff --git a/orc8r/cloud/go/services/ctraced/servicers/trace_servicer.go b/orc8r/cloud/go/services/ctraced/servicers/trace_servicer.go
new file mode 100644
index 000000000000..75f2895b0a1b
--- /dev/null
+++ b/orc8r/cloud/go/services/ctraced/servicers/trace_servicer.go
@@ -0,0 +1,97 @@
+/*
+Copyright 2020 The Magma Authors.
+
+This source code is licensed under the BSD-style license found in the
+LICENSE file in the root directory of this source tree.
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package servicers
+
+import (
+ "context"
+ "fmt"
+
+ "magma/orc8r/cloud/go/orc8r"
+ "magma/orc8r/cloud/go/serdes"
+ "magma/orc8r/cloud/go/services/configurator"
+ "magma/orc8r/cloud/go/services/ctraced/obsidian/models"
+ "magma/orc8r/cloud/go/services/ctraced/storage"
+ merrors "magma/orc8r/lib/go/errors"
+ "magma/orc8r/lib/go/protos"
+
+ "google.golang.org/grpc/codes"
+ "google.golang.org/grpc/status"
+)
+
+type callTraceServicer struct {
+ storage storage.CtracedStorage
+}
+
+func NewCallTraceServicer(storage storage.CtracedStorage) protos.CallTraceControllerServer {
+ return &callTraceServicer{storage: storage}
+}
+
+func (srv *callTraceServicer) ReportEndedCallTrace(ctx context.Context, req *protos.ReportEndedTraceRequest) (*protos.ReportEndedTraceResponse, error) {
+ networkID, err := getNetworkID(ctx)
+ if err != nil {
+ return nil, err
+ }
+ callTrace, err := getCallTraceModel(networkID, req.TraceId)
+ if err != nil {
+ return nil, err
+ }
+
+ err = srv.storage.StoreCallTrace(networkID, req.TraceId, req.TraceContent)
+ if err != nil {
+ return nil, status.Errorf(codes.Aborted, fmt.Sprintf("failed to save call trace data, network-id: %s, gateway-id: %s, calltrace-id: %s", networkID, callTrace.Config.GatewayID, req.TraceId))
+ }
+
+ callTrace.State.CallTraceEnding = req.Success
+ callTrace.State.CallTraceAvailable = req.Success
+
+ update := configurator.EntityUpdateCriteria{
+ Type: orc8r.CallTraceEntityType,
+ Key: req.TraceId,
+ NewConfig: callTrace,
+ }
+
+ _, err = configurator.UpdateEntity(networkID, update, serdes.Entity)
+ if err != nil {
+ return nil, status.Errorf(codes.Aborted, fmt.Sprintf("failed to update call trace, network-id: %s, gateway-id: %s, calltrace-id: %s", networkID, callTrace.Config.GatewayID, req.TraceId))
+ }
+ return &protos.ReportEndedTraceResponse{}, nil
+}
+
+func getNetworkID(ctx context.Context) (string, error) {
+ id, err := protos.GetGatewayIdentity(ctx)
+ if err != nil {
+ return "", err
+ }
+ return id.GetNetworkId(), nil
+}
+
+func getCallTraceModel(networkID string, callTraceID string) (*models.CallTrace, error) {
+ ent, err := configurator.LoadEntity(
+ networkID, orc8r.CallTraceEntityType, callTraceID,
+ configurator.EntityLoadCriteria{LoadConfig: true},
+ serdes.Entity,
+ )
+ if err == merrors.ErrNotFound {
+ return nil, status.Errorf(codes.InvalidArgument, "Call trace not found")
+ }
+ if err != nil {
+ return nil, status.Errorf(codes.InvalidArgument, "Failed to load call trace")
+ }
+ callTrace := &models.CallTrace{}
+ err = callTrace.FromBackendModels(ent)
+ if err != nil {
+ return nil, status.Errorf(codes.Aborted, "Failed to load call trace")
+ }
+ return callTrace, nil
+}
diff --git a/orc8r/cloud/go/services/ctraced/servicers/trace_servicer_test.go b/orc8r/cloud/go/services/ctraced/servicers/trace_servicer_test.go
new file mode 100644
index 000000000000..ecd8fc8203df
--- /dev/null
+++ b/orc8r/cloud/go/services/ctraced/servicers/trace_servicer_test.go
@@ -0,0 +1,101 @@
+/*
+Copyright 2020 The Magma Authors.
+
+This source code is licensed under the BSD-style license found in the
+LICENSE file in the root directory of this source tree.
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package servicers_test
+
+import (
+ "testing"
+
+ "magma/orc8r/cloud/go/orc8r"
+ "magma/orc8r/cloud/go/serdes"
+ "magma/orc8r/cloud/go/services/configurator"
+ "magma/orc8r/cloud/go/services/configurator/test_init"
+ models "magma/orc8r/cloud/go/services/ctraced/obsidian/models"
+ "magma/orc8r/cloud/go/services/ctraced/servicers"
+ "magma/orc8r/cloud/go/services/ctraced/storage"
+ deviceTestInit "magma/orc8r/cloud/go/services/device/test_init"
+ "magma/orc8r/cloud/go/test_utils"
+ "magma/orc8r/lib/go/protos"
+
+ "github.com/stretchr/testify/assert"
+ "golang.org/x/net/context"
+)
+
+func TestCallTraceServicer(t *testing.T) {
+ test_init.StartTestService(t)
+ deviceTestInit.StartTestService(t)
+
+ testNetworkId := "n1"
+ testGwHwId := "hw1"
+ testGwLogicalId := "g1"
+
+ // Initialize network
+ err := configurator.CreateNetwork(configurator.Network{ID: testNetworkId}, serdes.Network)
+ assert.NoError(t, err)
+
+ // Create a call trace
+ testTraceCfg := &models.CallTraceConfig{
+ TraceID: "CallTrace1",
+ GatewayID: "test_gateway_id",
+ Timeout: 300,
+ TraceType: models.CallTraceConfigTraceTypeGATEWAY,
+ }
+ testTrace := &models.CallTrace{
+ Config: testTraceCfg,
+ State: &models.CallTraceState{
+ CallTraceAvailable: false,
+ CallTraceEnding: false,
+ },
+ }
+ _, err = configurator.CreateEntity(
+ testNetworkId,
+ configurator.NetworkEntity{
+ Type: orc8r.CallTraceEntityType,
+ Key: "CallTrace1",
+ Config: testTrace,
+ },
+ serdes.Entity,
+ )
+ assert.NoError(t, err)
+
+ // Create an identity and context for sending requests as gateway
+ id := protos.Identity{}
+ idgw := protos.Identity_Gateway{HardwareId: testGwHwId, NetworkId: testNetworkId, LogicalId: testGwLogicalId}
+ id.SetGateway(&idgw)
+ ctx := id.NewContextWithIdentity(context.Background())
+
+ fact := test_utils.NewSQLBlobstore(t, "ctraced_trace_servicer_test_blobstore")
+ blobstore := storage.NewCtracedBlobstore(fact)
+ srv := servicers.NewCallTraceServicer(blobstore)
+
+ // Missing subscriber ID
+ req := &protos.ReportEndedTraceRequest{TraceId: "CallTrace0", Success: true, TraceContent: []byte("abcdefghijklmnopqrstuvwxyz\n")}
+ _, err = srv.ReportEndedCallTrace(ctx, req)
+ assert.EqualError(t, err, "rpc error: code = InvalidArgument desc = Call trace not found")
+
+ // Successfully ending the call trace
+ req = &protos.ReportEndedTraceRequest{TraceId: "CallTrace1", Success: true, TraceContent: []byte("abcdefghijklmnopqrstuvwxyz\n")}
+ _, err = srv.ReportEndedCallTrace(ctx, req)
+ assert.NoError(t, err)
+
+ // Verify that the call trace has ended
+ ent, err := configurator.LoadEntity(
+ testNetworkId, orc8r.CallTraceEntityType, "CallTrace1",
+ configurator.FullEntityLoadCriteria(),
+ serdes.Entity,
+ )
+ testCallTrace := (&models.CallTrace{}).FromEntity(ent)
+ assert.NoError(t, err)
+ assert.Equal(t, true, testCallTrace.State.CallTraceAvailable)
+ assert.Equal(t, true, testCallTrace.State.CallTraceEnding)
+}
diff --git a/orc8r/cloud/helm/orc8r/Chart.lock b/orc8r/cloud/helm/orc8r/Chart.lock
index 018265b2192d..42c3e04893e3 100644
--- a/orc8r/cloud/helm/orc8r/Chart.lock
+++ b/orc8r/cloud/helm/orc8r/Chart.lock
@@ -7,12 +7,12 @@ dependencies:
version: 1.4.22
- name: nms
repository: ""
- version: 0.1.10
+ version: 0.1.11
- name: logging
repository: ""
version: 0.1.10
- name: orc8rlib
repository: file://../orc8rlib
version: 0.1.2
-digest: sha256:7a49d5fba17dce594a8a6c4c89a7204678acca652c4b4d4727fc07f00132117d
-generated: "2021-03-05T11:56:20.589138693+05:30"
+digest: sha256:73383945a6f49b14bad2d42ffc0223286cd1d3f106319efc3739dc494547f08c
+generated: "2021-04-06T16:10:45.754709-07:00"
diff --git a/orc8r/cloud/helm/orc8r/Chart.yaml b/orc8r/cloud/helm/orc8r/Chart.yaml
index a30ece0e89f8..be1290677d9c 100644
--- a/orc8r/cloud/helm/orc8r/Chart.yaml
+++ b/orc8r/cloud/helm/orc8r/Chart.yaml
@@ -13,7 +13,7 @@ apiVersion: v2
appVersion: "1.0"
description: A Helm chart for magma orchestrator
name: orc8r
-version: 1.5.18
+version: 1.5.19
engine: gotpl
sources:
- https://github.com/magma/magma
@@ -31,7 +31,7 @@ dependencies:
repository: ""
condition: metrics.enabled
- name: nms
- version: 0.1.10
+ version: 0.1.11
repository: ""
condition: nms.enabled
- name: logging
diff --git a/orc8r/cloud/helm/orc8r/charts/nms/Chart.yaml b/orc8r/cloud/helm/orc8r/charts/nms/Chart.yaml
index f662ad3c29b0..4cfcf3296285 100644
--- a/orc8r/cloud/helm/orc8r/charts/nms/Chart.yaml
+++ b/orc8r/cloud/helm/orc8r/charts/nms/Chart.yaml
@@ -12,7 +12,7 @@
apiVersion: v1
description: Magma NMS
name: nms
-version: 0.1.10
+version: 0.1.11
home: https://github.com/magma/magma
sources:
- https://github.com/magma/magma
diff --git a/orc8r/cloud/helm/orc8r/charts/nms/templates/magmalte-deployment.yaml b/orc8r/cloud/helm/orc8r/charts/nms/templates/magmalte-deployment.yaml
index 3257b40755c2..47df3e6d6b26 100644
--- a/orc8r/cloud/helm/orc8r/charts/nms/templates/magmalte-deployment.yaml
+++ b/orc8r/cloud/helm/orc8r/charts/nms/templates/magmalte-deployment.yaml
@@ -80,6 +80,8 @@ spec:
value: {{ .Values.magmalte.env.mysql_db | quote }}
- name: MYSQL_HOST
value: {{ .Values.magmalte.env.mysql_host | quote }}
+ - name: MYSQL_PORT
+ value: {{ .Values.magmalte.env.mysql_port | quote }}
- name: MYSQL_DIALECT
value: {{ .Values.magmalte.env.mysql_dialect | quote }}
- name: MYSQL_PASS
diff --git a/orc8r/cloud/helm/orc8r/charts/nms/values.yaml b/orc8r/cloud/helm/orc8r/charts/nms/values.yaml
index ed1c888cad33..18cbe25308ea 100644
--- a/orc8r/cloud/helm/orc8r/charts/nms/values.yaml
+++ b/orc8r/cloud/helm/orc8r/charts/nms/values.yaml
@@ -30,10 +30,11 @@ magmalte:
port: 8081
mapbox_access_token: ""
mysql_host: mariadb.magma.svc.cluster.local
+ mysql_port: 5432
mysql_db: magma
mysql_user: magma
mysql_pass: password
- mysql_dialect: mysql
+ mysql_dialect: postgres
grafana_address: orc8r-user-grafana:3000
labels: {}
diff --git a/orc8r/gateway/c/common/async_grpc/GRPCReceiver.cpp b/orc8r/gateway/c/common/async_grpc/GRPCReceiver.cpp
index 5bf897a3d03a..ede96a227f13 100644
--- a/orc8r/gateway/c/common/async_grpc/GRPCReceiver.cpp
+++ b/orc8r/gateway/c/common/async_grpc/GRPCReceiver.cpp
@@ -10,8 +10,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
#include "GRPCReceiver.h"
-#include "magma_logging.h"
+#include // for operator<<, char_traits
+#include "magma_logging.h" // for MLOG
namespace magma {
diff --git a/orc8r/gateway/c/common/async_grpc/GRPCReceiver.h b/orc8r/gateway/c/common/async_grpc/GRPCReceiver.h
index 9c6c151790b1..7047309c9f15 100644
--- a/orc8r/gateway/c/common/async_grpc/GRPCReceiver.h
+++ b/orc8r/gateway/c/common/async_grpc/GRPCReceiver.h
@@ -12,9 +12,18 @@
*/
#pragma once
-#include
-#include
-#include
+#include // for ClientContext
+#include // for CompletionQueue
+#include // for Status
+#include // for uint32_t
+#include // for atomic
+#include // for operator+, seconds
+#include // for function
+#include // for unique_ptr
+namespace grpc {
+template
+class ClientAsyncResponseReader;
+}
namespace magma {
diff --git a/orc8r/gateway/c/common/config/MConfigLoader.cpp b/orc8r/gateway/c/common/config/MConfigLoader.cpp
index 60eca8937517..50d18680ab4c 100644
--- a/orc8r/gateway/c/common/config/MConfigLoader.cpp
+++ b/orc8r/gateway/c/common/config/MConfigLoader.cpp
@@ -11,15 +11,18 @@
* limitations under the License.
*/
-#include
-#include
-#include
-#include // JSON library
-#include
-#include
-
#include "MConfigLoader.h"
-#include "magma_logging.h"
+#include // for Status
+#include // for JsonStringToMessage
+#include // for getenv
+#include // for operator<<, char_traits
+#include // for basic_json<>::iterator
+#include "magma_logging.h" // for MLOG
+namespace google {
+namespace protobuf {
+class Message;
+}
+} // namespace google
using json = nlohmann::json;
diff --git a/orc8r/gateway/c/common/config/MConfigLoader.h b/orc8r/gateway/c/common/config/MConfigLoader.h
index c1c915ce1123..de24f7b56b4a 100644
--- a/orc8r/gateway/c/common/config/MConfigLoader.h
+++ b/orc8r/gateway/c/common/config/MConfigLoader.h
@@ -12,7 +12,13 @@
*/
#pragma once
-#include
+#include // for ifstream
+#include // for string
+namespace google {
+namespace protobuf {
+class Message;
+}
+} // namespace google
namespace magma {
diff --git a/orc8r/gateway/c/common/config/ServiceConfigLoader.cpp b/orc8r/gateway/c/common/config/ServiceConfigLoader.cpp
index 16e46f9387e8..9895cd2c02cb 100644
--- a/orc8r/gateway/c/common/config/ServiceConfigLoader.cpp
+++ b/orc8r/gateway/c/common/config/ServiceConfigLoader.cpp
@@ -11,12 +11,14 @@
* limitations under the License.
*/
-#include
-#include
-
#include "ServiceConfigLoader.h"
-#include "YAMLUtils.h"
-#include "magma_logging.h"
+#include // for BadFile
+#include // for Node::Node, Node::~Node
+#include // for LoadFile
+#include // for operator<<, basic_ostream
+#include // for allocator, operator+, char_traits
+#include "YAMLUtils.h" // for YAMLUtils
+#include "magma_logging.h" // for MLOG
namespace magma {
diff --git a/orc8r/gateway/c/common/config/ServiceConfigLoader.h b/orc8r/gateway/c/common/config/ServiceConfigLoader.h
index b7685a69e416..844eb0ed8a02 100644
--- a/orc8r/gateway/c/common/config/ServiceConfigLoader.h
+++ b/orc8r/gateway/c/common/config/ServiceConfigLoader.h
@@ -12,8 +12,8 @@
*/
#pragma once
-#include
-#include "yaml-cpp/yaml.h"
+#include // for Node
+#include // for string
namespace magma {
diff --git a/orc8r/gateway/c/common/config/YAMLUtils.cpp b/orc8r/gateway/c/common/config/YAMLUtils.cpp
index d4320c0509a1..adef4fcfc5e0 100644
--- a/orc8r/gateway/c/common/config/YAMLUtils.cpp
+++ b/orc8r/gateway/c/common/config/YAMLUtils.cpp
@@ -11,10 +11,10 @@
* limitations under the License.
*/
-#include
-
#include "YAMLUtils.h"
-#include "magma_logging.h"
+#include // IWYU pragma: keep
+#include // for operator!=, iterator_f...
+#include // for string
namespace magma {
diff --git a/orc8r/gateway/c/common/config/YAMLUtils.h b/orc8r/gateway/c/common/config/YAMLUtils.h
index 0d0b429edbf2..f29d5d70f9da 100644
--- a/orc8r/gateway/c/common/config/YAMLUtils.h
+++ b/orc8r/gateway/c/common/config/YAMLUtils.h
@@ -12,8 +12,7 @@
*/
#pragma once
-#include
-#include "yaml-cpp/yaml.h"
+#include // for Node
namespace magma {
diff --git a/orc8r/gateway/c/common/datastore/Serializers.cpp b/orc8r/gateway/c/common/datastore/Serializers.cpp
index 09c3a840e01c..88e636c54c61 100644
--- a/orc8r/gateway/c/common/datastore/Serializers.cpp
+++ b/orc8r/gateway/c/common/datastore/Serializers.cpp
@@ -10,8 +10,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
#include "Serializers.h"
-#include
+#include // for Message
+#include // for RedisState
using google::protobuf::Message;
using magma::orc8r::RedisState;
diff --git a/orc8r/gateway/c/common/datastore/Serializers.h b/orc8r/gateway/c/common/datastore/Serializers.h
index 41d5b6bb5149..8c7917840d70 100644
--- a/orc8r/gateway/c/common/datastore/Serializers.h
+++ b/orc8r/gateway/c/common/datastore/Serializers.h
@@ -12,8 +12,14 @@
*/
#pragma once
-#include
-#include
+#include // for uint64_t
+#include // for function
+#include // for string
+namespace google {
+namespace protobuf {
+class Message;
+}
+} // namespace google
using google::protobuf::Message;
namespace magma {
diff --git a/orc8r/gateway/c/common/eventd/EventdClient.cpp b/orc8r/gateway/c/common/eventd/EventdClient.cpp
index be15cbfbfd13..6d278c4adb56 100644
--- a/orc8r/gateway/c/common/eventd/EventdClient.cpp
+++ b/orc8r/gateway/c/common/eventd/EventdClient.cpp
@@ -11,17 +11,30 @@
* limitations under the License.
*/
#include "EventdClient.h"
-
-#include "ServiceRegistrySingleton.h"
-
-using grpc::ClientContext;
-using grpc::Status;
-using magma::orc8r::Event;
-using magma::orc8r::EventService;
-using magma::orc8r::Void;
+#include // for Channel
+#include // for default_delete
+#include // for move
+#include "ServiceRegistrySingleton.h" // for ServiceRegistrySin...
+#include "orc8r/protos/common.pb.h" // for Void
+#include "orc8r/protos/eventd.grpc.pb.h" // for EventService::Stub
+namespace grpc {
+class ClientContext;
+}
+namespace grpc {
+class Status;
+}
+namespace magma {
+namespace orc8r {
+class Event;
+}
+} // namespace magma
namespace magma {
+using orc8r::Event;
+using orc8r::EventService;
+using orc8r::Void;
+
AsyncEventdClient& AsyncEventdClient::getInstance() {
static AsyncEventdClient instance;
return instance;
diff --git a/orc8r/gateway/c/common/eventd/EventdClient.h b/orc8r/gateway/c/common/eventd/EventdClient.h
index 0fb36ed76ae1..274fcdd4c535 100644
--- a/orc8r/gateway/c/common/eventd/EventdClient.h
+++ b/orc8r/gateway/c/common/eventd/EventdClient.h
@@ -12,13 +12,24 @@
*/
#pragma once
-#include
-#include
-
-#include
-#include
-
-#include "GRPCReceiver.h"
+#include // for EventService::Stub, EventSe...
+#include // for uint32_t
+#include // for function
+#include // for unique_ptr
+#include "GRPCReceiver.h" // for GRPCReceiver
+namespace grpc {
+class Status;
+}
+namespace magma {
+namespace orc8r {
+class Event;
+}
+} // namespace magma
+namespace magma {
+namespace orc8r {
+class Void;
+}
+} // namespace magma
using grpc::Status;
diff --git a/orc8r/gateway/c/common/policydb/PolicyLoader.cpp b/orc8r/gateway/c/common/policydb/PolicyLoader.cpp
index d2f78f6c5c5f..3f6a8321aaa7 100644
--- a/orc8r/gateway/c/common/policydb/PolicyLoader.cpp
+++ b/orc8r/gateway/c/common/policydb/PolicyLoader.cpp
@@ -10,11 +10,23 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#include "RedisMap.hpp"
-#include "Serializers.h"
#include "PolicyLoader.h"
-#include "ServiceConfigLoader.h"
-#include "magma_logging.h"
+#include // for COMPACT_GOOGLE_LOG_INFO, LogMes...
+#include // IWYU pragma: keep
+#include // for seconds
+#include // for client, client::connect_state
+#include // for redis_error
+#include // for uint32_t
+#include // for make_shared, __shared_ptr, shar...
+#include // for operator<<, basic_ostream, size_t
+#include // for string, char_traits, operator<<
+#include // for sleep_for
+#include "ObjectMap.h" // for SUCCESS
+#include "RedisMap.hpp" // for RedisMap
+#include "Serializers.h" // for get_proto_deserializer, get_pro...
+#include "ServiceConfigLoader.h" // for ServiceConfigLoader
+#include "lte/protos/policydb.pb.h" // for PolicyRule
+#include "magma_logging.h" // for MLOG, MERROR, MDEBUG, MINFO
namespace magma {
diff --git a/orc8r/gateway/c/common/policydb/PolicyLoader.h b/orc8r/gateway/c/common/policydb/PolicyLoader.h
index 6d21eef0d939..1563c28d2c8c 100644
--- a/orc8r/gateway/c/common/policydb/PolicyLoader.h
+++ b/orc8r/gateway/c/common/policydb/PolicyLoader.h
@@ -10,10 +10,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#include
-#include
-#include
-#include
+#include // for uint32_t
+#include // for atomic
+#include // for function
+#include // for vector
+#include "lte/protos/subscriberdb.pb.h" // for lte
+namespace magma {
+namespace lte {
+class PolicyRule;
+}
+} // namespace magma
namespace magma {
using namespace lte;
diff --git a/orc8r/gateway/c/common/service303/MagmaService.cpp b/orc8r/gateway/c/common/service303/MagmaService.cpp
index 868c37554ab5..7e94934048e0 100644
--- a/orc8r/gateway/c/common/service303/MagmaService.cpp
+++ b/orc8r/gateway/c/common/service303/MagmaService.cpp
@@ -10,27 +10,38 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#include
-#include
-#include
-#include
-#include